1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include <rdma/ib_mad.h>
36#include <rdma/ib_smi.h>
37#include <rdma/ib_cache.h>
38#include <rdma/ib_sa.h>
39#include <rdma/ib_pack.h>
40#include <linux/mlx4/cmd.h>
41#include <linux/module.h>
42#include <linux/init.h>
43#include <linux/errno.h>
44#include <rdma/ib_user_verbs.h>
45#include <linux/delay.h>
46#include "mlx4_ib.h"
47
48
49
50
51
52
53struct mlx4_alias_guid_work_context {
54 u8 port;
55 struct mlx4_ib_dev *dev ;
56 struct ib_sa_query *sa_query;
57 struct completion done;
58 int query_id;
59 struct list_head list;
60 int block_num;
61};
62
63struct mlx4_next_alias_guid_work {
64 u8 port;
65 u8 block_num;
66 struct mlx4_sriov_alias_guid_info_rec_det rec_det;
67};
68
69
70void mlx4_ib_update_cache_on_guid_change(struct mlx4_ib_dev *dev, int block_num,
71 u8 port_num, u8 *p_data)
72{
73 int i;
74 u64 guid_indexes;
75 int slave_id;
76 int port_index = port_num - 1;
77
78 if (!mlx4_is_master(dev->dev))
79 return;
80
81 guid_indexes = be64_to_cpu((__force __be64) dev->sriov.alias_guid.
82 ports_guid[port_num - 1].
83 all_rec_per_port[block_num].guid_indexes);
84 pr_debug("port: %d, guid_indexes: 0x%llx\n", port_num, guid_indexes);
85
86 for (i = 0; i < NUM_ALIAS_GUID_IN_REC; i++) {
87
88
89 if (test_bit(i + 4, (unsigned long *)&guid_indexes)) {
90 slave_id = (block_num * NUM_ALIAS_GUID_IN_REC) + i ;
91 if (slave_id >= dev->dev->num_slaves) {
92 pr_debug("The last slave: %d\n", slave_id);
93 return;
94 }
95
96
97 memcpy(&dev->sriov.demux[port_index].guid_cache[slave_id],
98 &p_data[i * GUID_REC_SIZE],
99 GUID_REC_SIZE);
100 } else
101 pr_debug("Guid number: %d in block: %d"
102 " was not updated\n", i, block_num);
103 }
104}
105
106static __be64 get_cached_alias_guid(struct mlx4_ib_dev *dev, int port, int index)
107{
108 if (index >= NUM_ALIAS_GUID_PER_PORT) {
109 pr_err("%s: ERROR: asked for index:%d\n", __func__, index);
110 return (__force __be64) -1;
111 }
112 return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index];
113}
114
115
116ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index)
117{
118 return IB_SA_COMP_MASK(4 + index);
119}
120
121
122
123
124
125
126
127
128
129
130void mlx4_ib_notify_slaves_on_guid_change(struct mlx4_ib_dev *dev,
131 int block_num, u8 port_num,
132 u8 *p_data)
133{
134 int i;
135 u64 guid_indexes;
136 int slave_id;
137 enum slave_port_state new_state;
138 enum slave_port_state prev_state;
139 __be64 tmp_cur_ag, form_cache_ag;
140 enum slave_port_gen_event gen_event;
141
142 if (!mlx4_is_master(dev->dev))
143 return;
144
145 guid_indexes = be64_to_cpu((__force __be64) dev->sriov.alias_guid.
146 ports_guid[port_num - 1].
147 all_rec_per_port[block_num].guid_indexes);
148 pr_debug("port: %d, guid_indexes: 0x%llx\n", port_num, guid_indexes);
149
150
151 for (i = 0; i < NUM_ALIAS_GUID_IN_REC; i++) {
152
153 if (!(test_bit(i + 4, (unsigned long *)&guid_indexes)))
154 continue;
155
156 slave_id = (block_num * NUM_ALIAS_GUID_IN_REC) + i ;
157 if (slave_id >= dev->dev->num_vfs + 1)
158 return;
159 tmp_cur_ag = *(__be64 *)&p_data[i * GUID_REC_SIZE];
160 form_cache_ag = get_cached_alias_guid(dev, port_num,
161 (NUM_ALIAS_GUID_IN_REC * block_num) + i);
162
163
164
165
166
167 if (tmp_cur_ag != form_cache_ag)
168 continue;
169 mlx4_gen_guid_change_eqe(dev->dev, slave_id, port_num);
170
171
172
173 if (tmp_cur_ag != MLX4_NOT_SET_GUID) {
174 prev_state = mlx4_get_slave_port_state(dev->dev, slave_id, port_num);
175 new_state = set_and_calc_slave_port_state(dev->dev, slave_id, port_num,
176 MLX4_PORT_STATE_IB_PORT_STATE_EVENT_GID_VALID,
177 &gen_event);
178 pr_debug("slave: %d, port: %d prev_port_state: %d,"
179 " new_port_state: %d, gen_event: %d\n",
180 slave_id, port_num, prev_state, new_state, gen_event);
181 if (gen_event == SLAVE_PORT_GEN_EVENT_UP) {
182 pr_debug("sending PORT_UP event to slave: %d, port: %d\n",
183 slave_id, port_num);
184 mlx4_gen_port_state_change_eqe(dev->dev, slave_id,
185 port_num, MLX4_PORT_CHANGE_SUBTYPE_ACTIVE);
186 }
187 } else {
188 set_and_calc_slave_port_state(dev->dev, slave_id, port_num,
189 MLX4_PORT_STATE_IB_EVENT_GID_INVALID,
190 &gen_event);
191 pr_debug("sending PORT DOWN event to slave: %d, port: %d\n",
192 slave_id, port_num);
193 mlx4_gen_port_state_change_eqe(dev->dev, slave_id, port_num,
194 MLX4_PORT_CHANGE_SUBTYPE_DOWN);
195 }
196 }
197}
198
199static void aliasguid_query_handler(int status,
200 struct ib_sa_guidinfo_rec *guid_rec,
201 void *context)
202{
203 struct mlx4_ib_dev *dev;
204 struct mlx4_alias_guid_work_context *cb_ctx = context;
205 u8 port_index ;
206 int i;
207 struct mlx4_sriov_alias_guid_info_rec_det *rec;
208 unsigned long flags, flags1;
209
210 if (!context)
211 return;
212
213 dev = cb_ctx->dev;
214 port_index = cb_ctx->port - 1;
215 rec = &dev->sriov.alias_guid.ports_guid[port_index].
216 all_rec_per_port[cb_ctx->block_num];
217
218 if (status) {
219 rec->status = MLX4_GUID_INFO_STATUS_IDLE;
220 pr_debug("(port: %d) failed: status = %d\n",
221 cb_ctx->port, status);
222 goto out;
223 }
224
225 if (guid_rec->block_num != cb_ctx->block_num) {
226 pr_err("block num mismatch: %d != %d\n",
227 cb_ctx->block_num, guid_rec->block_num);
228 goto out;
229 }
230
231 pr_debug("lid/port: %d/%d, block_num: %d\n",
232 be16_to_cpu(guid_rec->lid), cb_ctx->port,
233 guid_rec->block_num);
234
235 rec = &dev->sriov.alias_guid.ports_guid[port_index].
236 all_rec_per_port[guid_rec->block_num];
237
238 rec->status = MLX4_GUID_INFO_STATUS_SET;
239 rec->method = MLX4_GUID_INFO_RECORD_SET;
240
241 for (i = 0 ; i < NUM_ALIAS_GUID_IN_REC; i++) {
242 __be64 tmp_cur_ag;
243 tmp_cur_ag = *(__be64 *)&guid_rec->guid_info_list[i * GUID_REC_SIZE];
244
245
246
247
248 if (tmp_cur_ag == MLX4_NOT_SET_GUID) {
249 mlx4_ib_warn(&dev->ib_dev, "%s:Record num %d in "
250 "block_num: %d was declined by SM, "
251 "ownership by %d (0 = driver, 1=sysAdmin,"
252 " 2=None)\n", __func__, i,
253 guid_rec->block_num, rec->ownership);
254 if (rec->ownership == MLX4_GUID_DRIVER_ASSIGN) {
255
256 *(__be64 *)&rec->all_recs[i * GUID_REC_SIZE] =
257 MLX4_NOT_SET_GUID;
258
259
260
261 rec->status = MLX4_GUID_INFO_STATUS_IDLE;
262 rec->guid_indexes |= mlx4_ib_get_aguid_comp_mask_from_ix(i);
263 }
264 } else {
265
266
267
268
269 if (rec->ownership == MLX4_GUID_SYSADMIN_ASSIGN &&
270 tmp_cur_ag != *(__be64 *)&rec->all_recs[i * GUID_REC_SIZE]) {
271
272 mlx4_ib_warn(&dev->ib_dev, "%s: Failed to set"
273 " admin guid after SysAdmin "
274 "configuration. "
275 "Record num %d in block_num:%d "
276 "was declined by SM, "
277 "new val(0x%llx) was kept\n",
278 __func__, i,
279 guid_rec->block_num,
280 be64_to_cpu(*(__be64 *) &
281 rec->all_recs[i * GUID_REC_SIZE]));
282 } else {
283 memcpy(&rec->all_recs[i * GUID_REC_SIZE],
284 &guid_rec->guid_info_list[i * GUID_REC_SIZE],
285 GUID_REC_SIZE);
286 }
287 }
288 }
289
290
291
292
293
294 mlx4_ib_notify_slaves_on_guid_change(dev, guid_rec->block_num,
295 cb_ctx->port,
296 guid_rec->guid_info_list);
297out:
298 spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
299 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
300 if (!dev->sriov.is_going_down)
301 queue_delayed_work(dev->sriov.alias_guid.ports_guid[port_index].wq,
302 &dev->sriov.alias_guid.ports_guid[port_index].
303 alias_guid_work, 0);
304 if (cb_ctx->sa_query) {
305 list_del(&cb_ctx->list);
306 kfree(cb_ctx);
307 } else
308 complete(&cb_ctx->done);
309 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
310 spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
311}
312
313static void invalidate_guid_record(struct mlx4_ib_dev *dev, u8 port, int index)
314{
315 int i;
316 u64 cur_admin_val;
317 ib_sa_comp_mask comp_mask = 0;
318
319 dev->sriov.alias_guid.ports_guid[port - 1].all_rec_per_port[index].status
320 = MLX4_GUID_INFO_STATUS_IDLE;
321 dev->sriov.alias_guid.ports_guid[port - 1].all_rec_per_port[index].method
322 = MLX4_GUID_INFO_RECORD_SET;
323
324
325 for (i = 0; i < NUM_ALIAS_GUID_IN_REC; i++) {
326 cur_admin_val =
327 *(u64 *)&dev->sriov.alias_guid.ports_guid[port - 1].
328 all_rec_per_port[index].all_recs[GUID_REC_SIZE * i];
329
330
331
332
333
334
335 if (MLX4_GUID_FOR_DELETE_VAL == cur_admin_val ||
336 (!index && !i) ||
337 MLX4_GUID_NONE_ASSIGN == dev->sriov.alias_guid.
338 ports_guid[port - 1].all_rec_per_port[index].ownership)
339 continue;
340 comp_mask |= mlx4_ib_get_aguid_comp_mask_from_ix(i);
341 }
342 dev->sriov.alias_guid.ports_guid[port - 1].
343 all_rec_per_port[index].guid_indexes = comp_mask;
344}
345
346static int set_guid_rec(struct ib_device *ibdev,
347 u8 port, int index,
348 struct mlx4_sriov_alias_guid_info_rec_det *rec_det)
349{
350 int err;
351 struct mlx4_ib_dev *dev = to_mdev(ibdev);
352 struct ib_sa_guidinfo_rec guid_info_rec;
353 ib_sa_comp_mask comp_mask;
354 struct ib_port_attr attr;
355 struct mlx4_alias_guid_work_context *callback_context;
356 unsigned long resched_delay, flags, flags1;
357 struct list_head *head =
358 &dev->sriov.alias_guid.ports_guid[port - 1].cb_list;
359
360 err = __mlx4_ib_query_port(ibdev, port, &attr, 1);
361 if (err) {
362 pr_debug("mlx4_ib_query_port failed (err: %d), port: %d\n",
363 err, port);
364 return err;
365 }
366
367 if (attr.state != IB_PORT_ACTIVE) {
368 pr_debug("port %d not active...rescheduling\n", port);
369 resched_delay = 5 * HZ;
370 err = -EAGAIN;
371 goto new_schedule;
372 }
373
374 callback_context = kmalloc(sizeof *callback_context, GFP_KERNEL);
375 if (!callback_context) {
376 err = -ENOMEM;
377 resched_delay = HZ * 5;
378 goto new_schedule;
379 }
380 callback_context->port = port;
381 callback_context->dev = dev;
382 callback_context->block_num = index;
383
384 memset(&guid_info_rec, 0, sizeof (struct ib_sa_guidinfo_rec));
385
386 guid_info_rec.lid = cpu_to_be16(attr.lid);
387 guid_info_rec.block_num = index;
388
389 memcpy(guid_info_rec.guid_info_list, rec_det->all_recs,
390 GUID_REC_SIZE * NUM_ALIAS_GUID_IN_REC);
391 comp_mask = IB_SA_GUIDINFO_REC_LID | IB_SA_GUIDINFO_REC_BLOCK_NUM |
392 rec_det->guid_indexes;
393
394 init_completion(&callback_context->done);
395 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
396 list_add_tail(&callback_context->list, head);
397 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
398
399 callback_context->query_id =
400 ib_sa_guid_info_rec_query(dev->sriov.alias_guid.sa_client,
401 ibdev, port, &guid_info_rec,
402 comp_mask, rec_det->method, 1000,
403 GFP_KERNEL, aliasguid_query_handler,
404 callback_context,
405 &callback_context->sa_query);
406 if (callback_context->query_id < 0) {
407 pr_debug("ib_sa_guid_info_rec_query failed, query_id: "
408 "%d. will reschedule to the next 1 sec.\n",
409 callback_context->query_id);
410 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
411 list_del(&callback_context->list);
412 kfree(callback_context);
413 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
414 resched_delay = 1 * HZ;
415 err = -EAGAIN;
416 goto new_schedule;
417 }
418 err = 0;
419 goto out;
420
421new_schedule:
422 spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
423 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
424 invalidate_guid_record(dev, port, index);
425 if (!dev->sriov.is_going_down) {
426 queue_delayed_work(dev->sriov.alias_guid.ports_guid[port - 1].wq,
427 &dev->sriov.alias_guid.ports_guid[port - 1].alias_guid_work,
428 resched_delay);
429 }
430 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
431 spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
432
433out:
434 return err;
435}
436
437void mlx4_ib_invalidate_all_guid_record(struct mlx4_ib_dev *dev, int port)
438{
439 int i;
440 unsigned long flags, flags1;
441
442 pr_debug("port %d\n", port);
443
444 spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
445 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
446 for (i = 0; i < NUM_ALIAS_GUID_REC_IN_PORT; i++)
447 invalidate_guid_record(dev, port, i);
448
449 if (mlx4_is_master(dev->dev) && !dev->sriov.is_going_down) {
450
451
452
453
454
455 cancel_delayed_work(&dev->sriov.alias_guid.
456 ports_guid[port - 1].alias_guid_work);
457 queue_delayed_work(dev->sriov.alias_guid.ports_guid[port - 1].wq,
458 &dev->sriov.alias_guid.ports_guid[port - 1].alias_guid_work,
459 0);
460 }
461 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
462 spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
463}
464
465
466
467static int get_next_record_to_update(struct mlx4_ib_dev *dev, u8 port,
468 struct mlx4_next_alias_guid_work *rec)
469{
470 int j;
471 unsigned long flags;
472
473 for (j = 0; j < NUM_ALIAS_GUID_REC_IN_PORT; j++) {
474 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags);
475 if (dev->sriov.alias_guid.ports_guid[port].all_rec_per_port[j].status ==
476 MLX4_GUID_INFO_STATUS_IDLE) {
477 memcpy(&rec->rec_det,
478 &dev->sriov.alias_guid.ports_guid[port].all_rec_per_port[j],
479 sizeof (struct mlx4_sriov_alias_guid_info_rec_det));
480 rec->port = port;
481 rec->block_num = j;
482 dev->sriov.alias_guid.ports_guid[port].all_rec_per_port[j].status =
483 MLX4_GUID_INFO_STATUS_PENDING;
484 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags);
485 return 0;
486 }
487 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags);
488 }
489 return -ENOENT;
490}
491
492static void set_administratively_guid_record(struct mlx4_ib_dev *dev, int port,
493 int rec_index,
494 struct mlx4_sriov_alias_guid_info_rec_det *rec_det)
495{
496 dev->sriov.alias_guid.ports_guid[port].all_rec_per_port[rec_index].guid_indexes =
497 rec_det->guid_indexes;
498 memcpy(dev->sriov.alias_guid.ports_guid[port].all_rec_per_port[rec_index].all_recs,
499 rec_det->all_recs, NUM_ALIAS_GUID_IN_REC * GUID_REC_SIZE);
500 dev->sriov.alias_guid.ports_guid[port].all_rec_per_port[rec_index].status =
501 rec_det->status;
502}
503
504static void set_all_slaves_guids(struct mlx4_ib_dev *dev, int port)
505{
506 int j;
507 struct mlx4_sriov_alias_guid_info_rec_det rec_det ;
508
509 for (j = 0 ; j < NUM_ALIAS_GUID_REC_IN_PORT ; j++) {
510 memset(rec_det.all_recs, 0, NUM_ALIAS_GUID_IN_REC * GUID_REC_SIZE);
511 rec_det.guid_indexes = (!j ? 0 : IB_SA_GUIDINFO_REC_GID0) |
512 IB_SA_GUIDINFO_REC_GID1 | IB_SA_GUIDINFO_REC_GID2 |
513 IB_SA_GUIDINFO_REC_GID3 | IB_SA_GUIDINFO_REC_GID4 |
514 IB_SA_GUIDINFO_REC_GID5 | IB_SA_GUIDINFO_REC_GID6 |
515 IB_SA_GUIDINFO_REC_GID7;
516 rec_det.status = MLX4_GUID_INFO_STATUS_IDLE;
517 set_administratively_guid_record(dev, port, j, &rec_det);
518 }
519}
520
521static void alias_guid_work(struct work_struct *work)
522{
523 struct delayed_work *delay = to_delayed_work(work);
524 int ret = 0;
525 struct mlx4_next_alias_guid_work *rec;
526 struct mlx4_sriov_alias_guid_port_rec_det *sriov_alias_port =
527 container_of(delay, struct mlx4_sriov_alias_guid_port_rec_det,
528 alias_guid_work);
529 struct mlx4_sriov_alias_guid *sriov_alias_guid = sriov_alias_port->parent;
530 struct mlx4_ib_sriov *ib_sriov = container_of(sriov_alias_guid,
531 struct mlx4_ib_sriov,
532 alias_guid);
533 struct mlx4_ib_dev *dev = container_of(ib_sriov, struct mlx4_ib_dev, sriov);
534
535 rec = kzalloc(sizeof *rec, GFP_KERNEL);
536 if (!rec) {
537 pr_err("alias_guid_work: No Memory\n");
538 return;
539 }
540
541 pr_debug("starting [port: %d]...\n", sriov_alias_port->port + 1);
542 ret = get_next_record_to_update(dev, sriov_alias_port->port, rec);
543 if (ret) {
544 pr_debug("No more records to update.\n");
545 goto out;
546 }
547
548 set_guid_rec(&dev->ib_dev, rec->port + 1, rec->block_num,
549 &rec->rec_det);
550
551out:
552 kfree(rec);
553}
554
555
556void mlx4_ib_init_alias_guid_work(struct mlx4_ib_dev *dev, int port)
557{
558 unsigned long flags, flags1;
559
560 if (!mlx4_is_master(dev->dev))
561 return;
562 spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
563 spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
564 if (!dev->sriov.is_going_down) {
565 queue_delayed_work(dev->sriov.alias_guid.ports_guid[port].wq,
566 &dev->sriov.alias_guid.ports_guid[port].alias_guid_work, 0);
567 }
568 spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
569 spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
570}
571
572void mlx4_ib_destroy_alias_guid_service(struct mlx4_ib_dev *dev)
573{
574 int i;
575 struct mlx4_ib_sriov *sriov = &dev->sriov;
576 struct mlx4_alias_guid_work_context *cb_ctx;
577 struct mlx4_sriov_alias_guid_port_rec_det *det;
578 struct ib_sa_query *sa_query;
579 unsigned long flags;
580
581 for (i = 0 ; i < dev->num_ports; i++) {
582 cancel_delayed_work(&dev->sriov.alias_guid.ports_guid[i].alias_guid_work);
583 det = &sriov->alias_guid.ports_guid[i];
584 spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags);
585 while (!list_empty(&det->cb_list)) {
586 cb_ctx = list_entry(det->cb_list.next,
587 struct mlx4_alias_guid_work_context,
588 list);
589 sa_query = cb_ctx->sa_query;
590 cb_ctx->sa_query = NULL;
591 list_del(&cb_ctx->list);
592 spin_unlock_irqrestore(&sriov->alias_guid.ag_work_lock, flags);
593 ib_sa_cancel_query(cb_ctx->query_id, sa_query);
594 wait_for_completion(&cb_ctx->done);
595 kfree(cb_ctx);
596 spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags);
597 }
598 spin_unlock_irqrestore(&sriov->alias_guid.ag_work_lock, flags);
599 }
600 for (i = 0 ; i < dev->num_ports; i++) {
601 flush_workqueue(dev->sriov.alias_guid.ports_guid[i].wq);
602 destroy_workqueue(dev->sriov.alias_guid.ports_guid[i].wq);
603 }
604 ib_sa_unregister_client(dev->sriov.alias_guid.sa_client);
605 kfree(dev->sriov.alias_guid.sa_client);
606}
607
608int mlx4_ib_init_alias_guid_service(struct mlx4_ib_dev *dev)
609{
610 char alias_wq_name[15];
611 int ret = 0;
612 int i, j, k;
613 union ib_gid gid;
614
615 if (!mlx4_is_master(dev->dev))
616 return 0;
617 dev->sriov.alias_guid.sa_client =
618 kzalloc(sizeof *dev->sriov.alias_guid.sa_client, GFP_KERNEL);
619 if (!dev->sriov.alias_guid.sa_client)
620 return -ENOMEM;
621
622 ib_sa_register_client(dev->sriov.alias_guid.sa_client);
623
624 spin_lock_init(&dev->sriov.alias_guid.ag_work_lock);
625
626 for (i = 1; i <= dev->num_ports; ++i) {
627 if (dev->ib_dev.query_gid(&dev->ib_dev , i, 0, &gid)) {
628 ret = -EFAULT;
629 goto err_unregister;
630 }
631 }
632
633 for (i = 0 ; i < dev->num_ports; i++) {
634 memset(&dev->sriov.alias_guid.ports_guid[i], 0,
635 sizeof (struct mlx4_sriov_alias_guid_port_rec_det));
636
637 for (j = 0; j < NUM_ALIAS_GUID_REC_IN_PORT; j++) {
638 if (mlx4_ib_sm_guid_assign) {
639 dev->sriov.alias_guid.ports_guid[i].
640 all_rec_per_port[j].
641 ownership = MLX4_GUID_DRIVER_ASSIGN;
642 continue;
643 }
644 dev->sriov.alias_guid.ports_guid[i].all_rec_per_port[j].
645 ownership = MLX4_GUID_NONE_ASSIGN;
646
647
648 for (k = 0; k < NUM_ALIAS_GUID_IN_REC; k++) {
649 *(__be64 *)&dev->sriov.alias_guid.ports_guid[i].
650 all_rec_per_port[j].all_recs[GUID_REC_SIZE * k] =
651 cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL);
652 }
653 }
654 INIT_LIST_HEAD(&dev->sriov.alias_guid.ports_guid[i].cb_list);
655
656 for (j = 0 ; j < NUM_ALIAS_GUID_REC_IN_PORT; j++)
657 invalidate_guid_record(dev, i + 1, j);
658
659 dev->sriov.alias_guid.ports_guid[i].parent = &dev->sriov.alias_guid;
660 dev->sriov.alias_guid.ports_guid[i].port = i;
661 if (mlx4_ib_sm_guid_assign)
662 set_all_slaves_guids(dev, i);
663
664 snprintf(alias_wq_name, sizeof alias_wq_name, "alias_guid%d", i);
665 dev->sriov.alias_guid.ports_guid[i].wq =
666 create_singlethread_workqueue(alias_wq_name);
667 if (!dev->sriov.alias_guid.ports_guid[i].wq) {
668 ret = -ENOMEM;
669 goto err_thread;
670 }
671 INIT_DELAYED_WORK(&dev->sriov.alias_guid.ports_guid[i].alias_guid_work,
672 alias_guid_work);
673 }
674 return 0;
675
676err_thread:
677 for (--i; i >= 0; i--) {
678 destroy_workqueue(dev->sriov.alias_guid.ports_guid[i].wq);
679 dev->sriov.alias_guid.ports_guid[i].wq = NULL;
680 }
681
682err_unregister:
683 ib_sa_unregister_client(dev->sriov.alias_guid.sa_client);
684 kfree(dev->sriov.alias_guid.sa_client);
685 dev->sriov.alias_guid.sa_client = NULL;
686 pr_err("init_alias_guid_service: Failed. (ret:%d)\n", ret);
687 return ret;
688}
689