41 #include <linux/module.h>
43 #include <linux/errno.h>
76 int port_index = port_num - 1;
78 if (!mlx4_is_master(dev->
dev))
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);
89 if (
test_bit(i + 4, (
unsigned long *)&guid_indexes)) {
91 if (slave_id >= dev->
dev->num_slaves) {
92 pr_debug(
"The last slave: %d\n", slave_id);
97 memcpy(&dev->
sriov.demux[port_index].guid_cache[slave_id],
101 pr_debug(
"Guid number: %d in block: %d"
102 " was not updated\n", i, block_num);
109 pr_err(
"%s: ERROR: asked for index:%d\n", __func__, index);
112 return *(
__be64 *)&dev->
sriov.demux[port - 1].guid_cache[index];
139 __be64 tmp_cur_ag, form_cache_ag;
142 if (!mlx4_is_master(dev->
dev))
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);
153 if (!(
test_bit(i + 4, (
unsigned long *)&guid_indexes)))
157 if (slave_id >= dev->
dev->num_slaves)
160 form_cache_ag = get_cached_alias_guid(dev, port_num,
161 (NUM_ALIAS_GUID_IN_REC * block_num) + i);
167 if (tmp_cur_ag != form_cache_ag)
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);
182 pr_debug(
"sending PORT_UP event to slave: %d, port: %d\n",
191 pr_debug(
"sending PORT DOWN event to slave: %d, port: %d\n",
199 static void aliasguid_query_handler(
int status,
214 port_index = cb_ctx->
port - 1;
215 rec = &dev->
sriov.alias_guid.ports_guid[port_index].
220 pr_debug(
"(port: %d) failed: status = %d\n",
221 cb_ctx->
port, status);
226 pr_err(
"block num mismatch: %d != %d\n",
231 pr_debug(
"lid/port: %d/%d, block_num: %d\n",
235 rec = &dev->
sriov.alias_guid.ports_guid[port_index].
250 "block_num: %d was declined by SM, "
251 "ownership by %d (0 = driver, 1=sysAdmin,"
252 " 2=None)\n", __func__, i,
273 " admin guid after SysAdmin "
275 "Record num %d in block_num:%d "
276 "was declined by SM, "
277 "new val(0x%llx) was kept\n",
300 if (!dev->
sriov.is_going_down)
302 &dev->
sriov.alias_guid.ports_guid[port_index].
309 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags1);
310 spin_unlock_irqrestore(&dev->
sriov.going_down_lock, flags);
313 static void invalidate_guid_record(
struct mlx4_ib_dev *dev,
u8 port,
int index)
319 dev->
sriov.alias_guid.ports_guid[port - 1].all_rec_per_port[
index].status
321 dev->
sriov.alias_guid.ports_guid[port - 1].all_rec_per_port[
index].method
327 *(
u64 *)&dev->
sriov.alias_guid.ports_guid[port - 1].
338 ports_guid[port - 1].all_rec_per_port[
index].ownership)
342 dev->
sriov.alias_guid.ports_guid[port - 1].
346 static int set_guid_rec(
struct ib_device *ibdev,
358 &dev->
sriov.alias_guid.ports_guid[port - 1].cb_list;
362 pr_debug(
"mlx4_ib_query_port failed (err: %d), port: %d\n",
368 pr_debug(
"port %d not active...rescheduling\n", port);
369 resched_delay = 5 *
HZ;
375 if (!callback_context) {
377 resched_delay =
HZ * 5;
381 callback_context->
dev =
dev;
387 guid_info_rec.block_num =
index;
394 init_completion(&callback_context->
done);
397 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags1);
401 ibdev, port, &guid_info_rec,
402 comp_mask, rec_det->
method, 1000,
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",
412 kfree(callback_context);
413 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags1);
414 resched_delay = 1 *
HZ;
424 invalidate_guid_record(dev, port, index);
425 if (!dev->
sriov.is_going_down) {
427 &dev->
sriov.alias_guid.ports_guid[port - 1].alias_guid_work,
430 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags1);
431 spin_unlock_irqrestore(&dev->
sriov.going_down_lock, flags);
447 invalidate_guid_record(dev, port, i);
449 if (mlx4_is_master(dev->
dev) && !dev->
sriov.is_going_down) {
456 ports_guid[port - 1].alias_guid_work);
458 &dev->
sriov.alias_guid.ports_guid[port - 1].alias_guid_work,
461 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags1);
462 spin_unlock_irqrestore(&dev->
sriov.going_down_lock, flags);
467 static int get_next_record_to_update(
struct mlx4_ib_dev *dev,
u8 port,
475 if (dev->
sriov.alias_guid.ports_guid[port].all_rec_per_port[j].status ==
478 &dev->
sriov.alias_guid.ports_guid[port].all_rec_per_port[j],
482 dev->
sriov.alias_guid.ports_guid[
port].all_rec_per_port[
j].status =
484 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags);
487 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags);
492 static void set_administratively_guid_record(
struct mlx4_ib_dev *dev,
int port,
496 dev->
sriov.alias_guid.ports_guid[
port].all_rec_per_port[rec_index].guid_indexes =
498 memcpy(dev->
sriov.alias_guid.ports_guid[port].all_rec_per_port[rec_index].all_recs,
500 dev->
sriov.alias_guid.ports_guid[
port].all_rec_per_port[rec_index].status =
504 static void set_all_slaves_guids(
struct mlx4_ib_dev *dev,
int port)
517 set_administratively_guid_record(dev, port, j, &rec_det);
537 pr_err(
"alias_guid_work: No Memory\n");
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);
544 pr_debug(
"No more records to update.\n");
560 if (!mlx4_is_master(dev->
dev))
564 if (!dev->
sriov.is_going_down) {
566 &dev->
sriov.alias_guid.ports_guid[port].alias_guid_work, 0);
568 spin_unlock_irqrestore(&dev->
sriov.alias_guid.ag_work_lock, flags1);
569 spin_unlock_irqrestore(&dev->
sriov.going_down_lock, flags);
585 while (!list_empty(&det->
cb_list)) {
592 spin_unlock_irqrestore(&sriov->
alias_guid.ag_work_lock, flags);
598 spin_unlock_irqrestore(&sriov->
alias_guid.ag_work_lock, flags);
610 char alias_wq_name[15];
615 if (!mlx4_is_master(dev->
dev))
617 dev->
sriov.alias_guid.sa_client =
619 if (!dev->
sriov.alias_guid.sa_client)
639 dev->
sriov.alias_guid.ports_guid[
i].
644 dev->
sriov.alias_guid.ports_guid[
i].all_rec_per_port[
j].
654 INIT_LIST_HEAD(&dev->
sriov.alias_guid.ports_guid[i].cb_list);
657 invalidate_guid_record(dev, i + 1, j);
659 dev->
sriov.alias_guid.ports_guid[
i].parent = &dev->
sriov.alias_guid;
660 dev->
sriov.alias_guid.ports_guid[
i].port =
i;
662 set_all_slaves_guids(dev, i);
664 snprintf(alias_wq_name,
sizeof alias_wq_name,
"alias_guid%d", i);
665 dev->
sriov.alias_guid.ports_guid[
i].wq =
667 if (!dev->
sriov.alias_guid.ports_guid[i].wq) {
677 for (--i; i >= 0; i--) {
679 dev->
sriov.alias_guid.ports_guid[
i].wq =
NULL;
686 pr_err(
"init_alias_guid_service: Failed. (ret:%d)\n", ret);