Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Copyright (c) 2012 Mellanox Technologies. All rights reserved.
  3 *
  4 * This software is available to you under a choice of one of two
  5 * licenses.  You may choose to be licensed under the terms of the GNU
  6 * General Public License (GPL) Version 2, available from the file
  7 * COPYING in the main directory of this source tree, or the
  8 * OpenIB.org BSD license below:
  9 *
 10 *     Redistribution and use in source and binary forms, with or
 11 *     without modification, are permitted provided that the following
 12 *     conditions are met:
 13 *
 14 *      - Redistributions of source code must retain the above
 15 *        copyright notice, this list of conditions and the following
 16 *        disclaimer.
 17 *
 18 *      - Redistributions in binary form must reproduce the above
 19 *        copyright notice, this list of conditions and the following
 20 *        disclaimer in the documentation and/or other materials
 21 *        provided with the distribution.
 22 *
 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 30 * SOFTWARE.
 31 */
 32 /***********************************************************/
 33/*This file support the handling of the Alias GUID feature. */
 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/*
 49The driver keeps the current state of all guids, as they are in the HW.
 50Whenever we receive an smp mad GUIDInfo record, the data will be cached.
 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	ib_sa_comp_mask		guid_indexes;
 62	u8			method;
 63};
 64
 65struct mlx4_next_alias_guid_work {
 66	u8 port;
 67	u8 block_num;
 68	u8 method;
 69	struct mlx4_sriov_alias_guid_info_rec_det rec_det;
 70};
 71
 72static int get_low_record_time_index(struct mlx4_ib_dev *dev, u8 port,
 73				     int *resched_delay_sec);
 74
 75void mlx4_ib_update_cache_on_guid_change(struct mlx4_ib_dev *dev, int block_num,
 76					 u8 port_num, u8 *p_data)
 77{
 78	int i;
 79	u64 guid_indexes;
 80	int slave_id;
 81	int port_index = port_num - 1;
 82
 83	if (!mlx4_is_master(dev->dev))
 84		return;
 85
 86	guid_indexes = be64_to_cpu((__force __be64) dev->sriov.alias_guid.
 87				   ports_guid[port_num - 1].
 88				   all_rec_per_port[block_num].guid_indexes);
 89	pr_debug("port: %d, guid_indexes: 0x%llx\n", port_num, guid_indexes);
 90
 91	for (i = 0; i < NUM_ALIAS_GUID_IN_REC; i++) {
 92		/* The location of the specific index starts from bit number 4
 93		 * until bit num 11 */
 94		if (test_bit(i + 4, (unsigned long *)&guid_indexes)) {
 95			slave_id = (block_num * NUM_ALIAS_GUID_IN_REC) + i ;
 96			if (slave_id >= dev->dev->num_slaves) {
 97				pr_debug("The last slave: %d\n", slave_id);
 98				return;
 99			}
100
101			/* cache the guid: */
102			memcpy(&dev->sriov.demux[port_index].guid_cache[slave_id],
103			       &p_data[i * GUID_REC_SIZE],
104			       GUID_REC_SIZE);
105		} else
106			pr_debug("Guid number: %d in block: %d"
107				 " was not updated\n", i, block_num);
108	}
109}
110
111static __be64 get_cached_alias_guid(struct mlx4_ib_dev *dev, int port, int index)
112{
113	if (index >= NUM_ALIAS_GUID_PER_PORT) {
114		pr_err("%s: ERROR: asked for index:%d\n", __func__, index);
115		return (__force __be64) -1;
116	}
117	return *(__be64 *)&dev->sriov.demux[port - 1].guid_cache[index];
118}
119
120
121ib_sa_comp_mask mlx4_ib_get_aguid_comp_mask_from_ix(int index)
122{
123	return IB_SA_COMP_MASK(4 + index);
124}
125
126void mlx4_ib_slave_alias_guid_event(struct mlx4_ib_dev *dev, int slave,
127				    int port,  int slave_init)
128{
129	__be64 curr_guid, required_guid;
130	int record_num = slave / 8;
131	int index = slave % 8;
132	int port_index = port - 1;
133	unsigned long flags;
134	int do_work = 0;
135
136	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags);
137	if (dev->sriov.alias_guid.ports_guid[port_index].state_flags &
138	    GUID_STATE_NEED_PORT_INIT)
139		goto unlock;
140	if (!slave_init) {
141		curr_guid = *(__be64 *)&dev->sriov.
142			alias_guid.ports_guid[port_index].
143			all_rec_per_port[record_num].
144			all_recs[GUID_REC_SIZE * index];
145		if (curr_guid == cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL) ||
146		    !curr_guid)
147			goto unlock;
148		required_guid = cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL);
149	} else {
150		required_guid = mlx4_get_admin_guid(dev->dev, slave, port);
151		if (required_guid == cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL))
152			goto unlock;
153	}
154	*(__be64 *)&dev->sriov.alias_guid.ports_guid[port_index].
155		all_rec_per_port[record_num].
156		all_recs[GUID_REC_SIZE * index] = required_guid;
157	dev->sriov.alias_guid.ports_guid[port_index].
158		all_rec_per_port[record_num].guid_indexes
159		|= mlx4_ib_get_aguid_comp_mask_from_ix(index);
160	dev->sriov.alias_guid.ports_guid[port_index].
161		all_rec_per_port[record_num].status
162		= MLX4_GUID_INFO_STATUS_IDLE;
163	/* set to run immediately */
164	dev->sriov.alias_guid.ports_guid[port_index].
165		all_rec_per_port[record_num].time_to_run = 0;
166	dev->sriov.alias_guid.ports_guid[port_index].
167		all_rec_per_port[record_num].
168		guids_retry_schedule[index] = 0;
169	do_work = 1;
170unlock:
171	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags);
172
173	if (do_work)
174		mlx4_ib_init_alias_guid_work(dev, port_index);
175}
176
177/*
178 * Whenever new GUID is set/unset (guid table change) create event and
179 * notify the relevant slave (master also should be notified).
180 * If the GUID value is not as we have in the cache the slave will not be
181 * updated; in this case it waits for the smp_snoop or the port management
182 * event to call the function and to update the slave.
183 * block_number - the index of the block (16 blocks available)
184 * port_number - 1 or 2
185 */
186void mlx4_ib_notify_slaves_on_guid_change(struct mlx4_ib_dev *dev,
187					  int block_num, u8 port_num,
188					  u8 *p_data)
189{
190	int i;
191	u64 guid_indexes;
192	int slave_id, slave_port;
193	enum slave_port_state new_state;
194	enum slave_port_state prev_state;
195	__be64 tmp_cur_ag, form_cache_ag;
196	enum slave_port_gen_event gen_event;
197	struct mlx4_sriov_alias_guid_info_rec_det *rec;
198	unsigned long flags;
199	__be64 required_value;
200
201	if (!mlx4_is_master(dev->dev))
202		return;
203
204	rec = &dev->sriov.alias_guid.ports_guid[port_num - 1].
205			all_rec_per_port[block_num];
206	guid_indexes = be64_to_cpu((__force __be64) dev->sriov.alias_guid.
207				   ports_guid[port_num - 1].
208				   all_rec_per_port[block_num].guid_indexes);
209	pr_debug("port: %d, guid_indexes: 0x%llx\n", port_num, guid_indexes);
210
211	/*calculate the slaves and notify them*/
212	for (i = 0; i < NUM_ALIAS_GUID_IN_REC; i++) {
213		/* the location of the specific index runs from bits 4..11 */
214		if (!(test_bit(i + 4, (unsigned long *)&guid_indexes)))
215			continue;
216
217		slave_id = (block_num * NUM_ALIAS_GUID_IN_REC) + i ;
218		if (slave_id >= dev->dev->persist->num_vfs + 1)
219			return;
220
221		slave_port = mlx4_phys_to_slave_port(dev->dev, slave_id, port_num);
222		if (slave_port < 0) /* this port isn't available for the VF */
223			continue;
224
225		tmp_cur_ag = *(__be64 *)&p_data[i * GUID_REC_SIZE];
226		form_cache_ag = get_cached_alias_guid(dev, port_num,
227					(NUM_ALIAS_GUID_IN_REC * block_num) + i);
228		/*
229		 * Check if guid is not the same as in the cache,
230		 * If it is different, wait for the snoop_smp or the port mgmt
231		 * change event to update the slave on its port state change
232		 */
233		if (tmp_cur_ag != form_cache_ag)
234			continue;
235
236		spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags);
237		required_value = *(__be64 *)&rec->all_recs[i * GUID_REC_SIZE];
238
239		if (required_value == cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL))
240			required_value = 0;
241
242		if (tmp_cur_ag == required_value) {
243			rec->guid_indexes = rec->guid_indexes &
244			       ~mlx4_ib_get_aguid_comp_mask_from_ix(i);
245		} else {
246			/* may notify port down if value is 0 */
247			if (tmp_cur_ag != MLX4_NOT_SET_GUID) {
248				spin_unlock_irqrestore(&dev->sriov.
249					alias_guid.ag_work_lock, flags);
250				continue;
251			}
252		}
253		spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock,
254				       flags);
255		mlx4_gen_guid_change_eqe(dev->dev, slave_id, port_num);
256		/*2 cases: Valid GUID, and Invalid Guid*/
257
258		if (tmp_cur_ag != MLX4_NOT_SET_GUID) { /*valid GUID*/
259			prev_state = mlx4_get_slave_port_state(dev->dev, slave_id, port_num);
260			new_state = set_and_calc_slave_port_state(dev->dev, slave_id, port_num,
261								  MLX4_PORT_STATE_IB_PORT_STATE_EVENT_GID_VALID,
262								  &gen_event);
263			pr_debug("slave: %d, port: %d prev_port_state: %d,"
264				 " new_port_state: %d, gen_event: %d\n",
265				 slave_id, port_num, prev_state, new_state, gen_event);
266			if (gen_event == SLAVE_PORT_GEN_EVENT_UP) {
267				pr_debug("sending PORT_UP event to slave: %d, port: %d\n",
268					 slave_id, port_num);
269				mlx4_gen_port_state_change_eqe(dev->dev, slave_id,
270							       port_num, MLX4_PORT_CHANGE_SUBTYPE_ACTIVE);
271			}
272		} else { /* request to invalidate GUID */
273			set_and_calc_slave_port_state(dev->dev, slave_id, port_num,
274						      MLX4_PORT_STATE_IB_EVENT_GID_INVALID,
275						      &gen_event);
276			if (gen_event == SLAVE_PORT_GEN_EVENT_DOWN) {
277				pr_debug("sending PORT DOWN event to slave: %d, port: %d\n",
278					 slave_id, port_num);
279				mlx4_gen_port_state_change_eqe(dev->dev,
280							       slave_id,
281							       port_num,
282							       MLX4_PORT_CHANGE_SUBTYPE_DOWN);
283			}
284		}
285	}
286}
287
288static void aliasguid_query_handler(int status,
289				    struct ib_sa_guidinfo_rec *guid_rec,
290				    void *context)
291{
292	struct mlx4_ib_dev *dev;
293	struct mlx4_alias_guid_work_context *cb_ctx = context;
294	u8 port_index ;
295	int i;
296	struct mlx4_sriov_alias_guid_info_rec_det *rec;
297	unsigned long flags, flags1;
298	ib_sa_comp_mask declined_guid_indexes = 0;
299	ib_sa_comp_mask applied_guid_indexes = 0;
300	unsigned int resched_delay_sec = 0;
301
302	if (!context)
303		return;
304
305	dev = cb_ctx->dev;
306	port_index = cb_ctx->port - 1;
307	rec = &dev->sriov.alias_guid.ports_guid[port_index].
308		all_rec_per_port[cb_ctx->block_num];
309
310	if (status) {
311		pr_debug("(port: %d) failed: status = %d\n",
312			 cb_ctx->port, status);
313		rec->time_to_run = ktime_get_boottime_ns() + 1 * NSEC_PER_SEC;
314		goto out;
315	}
316
317	if (guid_rec->block_num != cb_ctx->block_num) {
318		pr_err("block num mismatch: %d != %d\n",
319		       cb_ctx->block_num, guid_rec->block_num);
320		goto out;
321	}
322
323	pr_debug("lid/port: %d/%d, block_num: %d\n",
324		 be16_to_cpu(guid_rec->lid), cb_ctx->port,
325		 guid_rec->block_num);
326
327	rec = &dev->sriov.alias_guid.ports_guid[port_index].
328		all_rec_per_port[guid_rec->block_num];
329
330	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags);
331	for (i = 0 ; i < NUM_ALIAS_GUID_IN_REC; i++) {
332		__be64 sm_response, required_val;
333
334		if (!(cb_ctx->guid_indexes &
335			mlx4_ib_get_aguid_comp_mask_from_ix(i)))
336			continue;
337		sm_response = *(__be64 *)&guid_rec->guid_info_list
338				[i * GUID_REC_SIZE];
339		required_val = *(__be64 *)&rec->all_recs[i * GUID_REC_SIZE];
340		if (cb_ctx->method == MLX4_GUID_INFO_RECORD_DELETE) {
341			if (required_val ==
342			    cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL))
343				goto next_entry;
344
345			/* A new value was set till we got the response */
346			pr_debug("need to set new value %llx, record num %d, block_num:%d\n",
347				 be64_to_cpu(required_val),
348				 i, guid_rec->block_num);
349			goto entry_declined;
350		}
351
352		/* check if the SM didn't assign one of the records.
353		 * if it didn't, re-ask for.
354		 */
355		if (sm_response == MLX4_NOT_SET_GUID) {
356			if (rec->guids_retry_schedule[i] == 0)
357				mlx4_ib_warn(&dev->ib_dev,
358					     "%s:Record num %d in  block_num: %d was declined by SM\n",
359					     __func__, i,
360					     guid_rec->block_num);
361			goto entry_declined;
362		} else {
363		       /* properly assigned record. */
364		       /* We save the GUID we just got from the SM in the
365			* admin_guid in order to be persistent, and in the
366			* request from the sm the process will ask for the same GUID */
367			if (required_val &&
368			    sm_response != required_val) {
369				/* Warn only on first retry */
370				if (rec->guids_retry_schedule[i] == 0)
371					mlx4_ib_warn(&dev->ib_dev, "%s: Failed to set"
372						     " admin guid after SysAdmin "
373						     "configuration. "
374						     "Record num %d in block_num:%d "
375						     "was declined by SM, "
376						     "new val(0x%llx) was kept, SM returned (0x%llx)\n",
377						      __func__, i,
378						     guid_rec->block_num,
379						     be64_to_cpu(required_val),
380						     be64_to_cpu(sm_response));
381				goto entry_declined;
382			} else {
383				*(__be64 *)&rec->all_recs[i * GUID_REC_SIZE] =
384					sm_response;
385				if (required_val == 0)
386					mlx4_set_admin_guid(dev->dev,
387							    sm_response,
388							    (guid_rec->block_num
389							    * NUM_ALIAS_GUID_IN_REC) + i,
390							    cb_ctx->port);
391				goto next_entry;
392			}
393		}
394entry_declined:
395		declined_guid_indexes |= mlx4_ib_get_aguid_comp_mask_from_ix(i);
396		rec->guids_retry_schedule[i] =
397			(rec->guids_retry_schedule[i] == 0) ?  1 :
398			min((unsigned int)60,
399			    rec->guids_retry_schedule[i] * 2);
400		/* using the minimum value among all entries in that record */
401		resched_delay_sec = (resched_delay_sec == 0) ?
402				rec->guids_retry_schedule[i] :
403				min(resched_delay_sec,
404				    rec->guids_retry_schedule[i]);
405		continue;
406
407next_entry:
408		rec->guids_retry_schedule[i] = 0;
409	}
410
411	applied_guid_indexes =  cb_ctx->guid_indexes & ~declined_guid_indexes;
412	if (declined_guid_indexes ||
413	    rec->guid_indexes & ~(applied_guid_indexes)) {
414		pr_debug("record=%d wasn't fully set, guid_indexes=0x%llx applied_indexes=0x%llx, declined_indexes=0x%llx\n",
415			 guid_rec->block_num,
416			 be64_to_cpu((__force __be64)rec->guid_indexes),
417			 be64_to_cpu((__force __be64)applied_guid_indexes),
418			 be64_to_cpu((__force __be64)declined_guid_indexes));
419		rec->time_to_run = ktime_get_boottime_ns() +
420			resched_delay_sec * NSEC_PER_SEC;
421	} else {
422		rec->status = MLX4_GUID_INFO_STATUS_SET;
423	}
424	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags);
425	/*
426	The func is call here to close the cases when the
427	sm doesn't send smp, so in the sa response the driver
428	notifies the slave.
429	*/
430	mlx4_ib_notify_slaves_on_guid_change(dev, guid_rec->block_num,
431					     cb_ctx->port,
432					     guid_rec->guid_info_list);
433out:
434	spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
435	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
436	if (!dev->sriov.is_going_down) {
437		get_low_record_time_index(dev, port_index, &resched_delay_sec);
438		queue_delayed_work(dev->sriov.alias_guid.ports_guid[port_index].wq,
439				   &dev->sriov.alias_guid.ports_guid[port_index].
440				   alias_guid_work,
441				   msecs_to_jiffies(resched_delay_sec * 1000));
442	}
443	if (cb_ctx->sa_query) {
444		list_del(&cb_ctx->list);
445		kfree(cb_ctx);
446	} else
447		complete(&cb_ctx->done);
448	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
449	spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
450}
451
452static void invalidate_guid_record(struct mlx4_ib_dev *dev, u8 port, int index)
453{
454	int i;
455	u64 cur_admin_val;
456	ib_sa_comp_mask comp_mask = 0;
457
458	dev->sriov.alias_guid.ports_guid[port - 1].all_rec_per_port[index].status
459		= MLX4_GUID_INFO_STATUS_SET;
460
461	/* calculate the comp_mask for that record.*/
462	for (i = 0; i < NUM_ALIAS_GUID_IN_REC; i++) {
463		cur_admin_val =
464			*(u64 *)&dev->sriov.alias_guid.ports_guid[port - 1].
465			all_rec_per_port[index].all_recs[GUID_REC_SIZE * i];
466		/*
467		check the admin value: if it's for delete (~00LL) or
468		it is the first guid of the first record (hw guid) or
469		the records is not in ownership of the sysadmin and the sm doesn't
470		need to assign GUIDs, then don't put it up for assignment.
471		*/
472		if (MLX4_GUID_FOR_DELETE_VAL == cur_admin_val ||
473		    (!index && !i))
474			continue;
475		comp_mask |= mlx4_ib_get_aguid_comp_mask_from_ix(i);
476	}
477	dev->sriov.alias_guid.ports_guid[port - 1].
478		all_rec_per_port[index].guid_indexes |= comp_mask;
479	if (dev->sriov.alias_guid.ports_guid[port - 1].
480	    all_rec_per_port[index].guid_indexes)
481		dev->sriov.alias_guid.ports_guid[port - 1].
482		all_rec_per_port[index].status = MLX4_GUID_INFO_STATUS_IDLE;
483
484}
485
486static int set_guid_rec(struct ib_device *ibdev,
487			struct mlx4_next_alias_guid_work *rec)
488{
489	int err;
490	struct mlx4_ib_dev *dev = to_mdev(ibdev);
491	struct ib_sa_guidinfo_rec guid_info_rec;
492	ib_sa_comp_mask comp_mask;
493	struct ib_port_attr attr;
494	struct mlx4_alias_guid_work_context *callback_context;
495	unsigned long resched_delay, flags, flags1;
496	u8 port = rec->port + 1;
497	int index = rec->block_num;
498	struct mlx4_sriov_alias_guid_info_rec_det *rec_det = &rec->rec_det;
499	struct list_head *head =
500		&dev->sriov.alias_guid.ports_guid[port - 1].cb_list;
501
502	memset(&attr, 0, sizeof(attr));
503	err = __mlx4_ib_query_port(ibdev, port, &attr, 1);
504	if (err) {
505		pr_debug("mlx4_ib_query_port failed (err: %d), port: %d\n",
506			 err, port);
507		return err;
508	}
509	/*check the port was configured by the sm, otherwise no need to send */
510	if (attr.state != IB_PORT_ACTIVE) {
511		pr_debug("port %d not active...rescheduling\n", port);
512		resched_delay = 5 * HZ;
513		err = -EAGAIN;
514		goto new_schedule;
515	}
516
517	callback_context = kmalloc(sizeof *callback_context, GFP_KERNEL);
518	if (!callback_context) {
519		err = -ENOMEM;
520		resched_delay = HZ * 5;
521		goto new_schedule;
522	}
523	callback_context->port = port;
524	callback_context->dev = dev;
525	callback_context->block_num = index;
526	callback_context->guid_indexes = rec_det->guid_indexes;
527	callback_context->method = rec->method;
528
529	memset(&guid_info_rec, 0, sizeof (struct ib_sa_guidinfo_rec));
530
531	guid_info_rec.lid = ib_lid_be16(attr.lid);
532	guid_info_rec.block_num = index;
533
534	memcpy(guid_info_rec.guid_info_list, rec_det->all_recs,
535	       GUID_REC_SIZE * NUM_ALIAS_GUID_IN_REC);
536	comp_mask = IB_SA_GUIDINFO_REC_LID | IB_SA_GUIDINFO_REC_BLOCK_NUM |
537		rec_det->guid_indexes;
538
539	init_completion(&callback_context->done);
540	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
541	list_add_tail(&callback_context->list, head);
542	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
543
544	callback_context->query_id =
545		ib_sa_guid_info_rec_query(dev->sriov.alias_guid.sa_client,
546					  ibdev, port, &guid_info_rec,
547					  comp_mask, rec->method, 1000,
548					  GFP_KERNEL, aliasguid_query_handler,
549					  callback_context,
550					  &callback_context->sa_query);
551	if (callback_context->query_id < 0) {
552		pr_debug("ib_sa_guid_info_rec_query failed, query_id: "
553			 "%d. will reschedule to the next 1 sec.\n",
554			 callback_context->query_id);
555		spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
556		list_del(&callback_context->list);
557		kfree(callback_context);
558		spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
559		resched_delay = 1 * HZ;
560		err = -EAGAIN;
561		goto new_schedule;
562	}
563	err = 0;
564	goto out;
565
566new_schedule:
567	spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
568	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
569	invalidate_guid_record(dev, port, index);
570	if (!dev->sriov.is_going_down) {
571		queue_delayed_work(dev->sriov.alias_guid.ports_guid[port - 1].wq,
572				   &dev->sriov.alias_guid.ports_guid[port - 1].alias_guid_work,
573				   resched_delay);
574	}
575	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
576	spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
577
578out:
579	return err;
580}
581
582static void mlx4_ib_guid_port_init(struct mlx4_ib_dev *dev, int port)
583{
584	int j, k, entry;
585	__be64 guid;
586
587	/*Check if the SM doesn't need to assign the GUIDs*/
588	for (j = 0; j < NUM_ALIAS_GUID_REC_IN_PORT; j++) {
589		for (k = 0; k < NUM_ALIAS_GUID_IN_REC; k++) {
590			entry = j * NUM_ALIAS_GUID_IN_REC + k;
591			/* no request for the 0 entry (hw guid) */
592			if (!entry || entry > dev->dev->persist->num_vfs ||
593			    !mlx4_is_slave_active(dev->dev, entry))
594				continue;
595			guid = mlx4_get_admin_guid(dev->dev, entry, port);
596			*(__be64 *)&dev->sriov.alias_guid.ports_guid[port - 1].
597				all_rec_per_port[j].all_recs
598				[GUID_REC_SIZE * k] = guid;
599			pr_debug("guid was set, entry=%d, val=0x%llx, port=%d\n",
600				 entry,
601				 be64_to_cpu(guid),
602				 port);
603		}
604	}
605}
606void mlx4_ib_invalidate_all_guid_record(struct mlx4_ib_dev *dev, int port)
607{
608	int i;
609	unsigned long flags, flags1;
610
611	pr_debug("port %d\n", port);
612
613	spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
614	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
615
616	if (dev->sriov.alias_guid.ports_guid[port - 1].state_flags &
617		GUID_STATE_NEED_PORT_INIT) {
618		mlx4_ib_guid_port_init(dev, port);
619		dev->sriov.alias_guid.ports_guid[port - 1].state_flags &=
620			(~GUID_STATE_NEED_PORT_INIT);
621	}
622	for (i = 0; i < NUM_ALIAS_GUID_REC_IN_PORT; i++)
623		invalidate_guid_record(dev, port, i);
624
625	if (mlx4_is_master(dev->dev) && !dev->sriov.is_going_down) {
626		/*
627		make sure no work waits in the queue, if the work is already
628		queued(not on the timer) the cancel will fail. That is not a problem
629		because we just want the work started.
630		*/
631		cancel_delayed_work(&dev->sriov.alias_guid.
632				      ports_guid[port - 1].alias_guid_work);
633		queue_delayed_work(dev->sriov.alias_guid.ports_guid[port - 1].wq,
634				   &dev->sriov.alias_guid.ports_guid[port - 1].alias_guid_work,
635				   0);
636	}
637	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
638	spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
639}
640
641static void set_required_record(struct mlx4_ib_dev *dev, u8 port,
642				struct mlx4_next_alias_guid_work *next_rec,
643				int record_index)
644{
645	int i;
646	int lowset_time_entry = -1;
647	int lowest_time = 0;
648	ib_sa_comp_mask delete_guid_indexes = 0;
649	ib_sa_comp_mask set_guid_indexes = 0;
650	struct mlx4_sriov_alias_guid_info_rec_det *rec =
651			&dev->sriov.alias_guid.ports_guid[port].
652			all_rec_per_port[record_index];
653
654	for (i = 0; i < NUM_ALIAS_GUID_IN_REC; i++) {
655		if (!(rec->guid_indexes &
656			mlx4_ib_get_aguid_comp_mask_from_ix(i)))
657			continue;
658
659		if (*(__be64 *)&rec->all_recs[i * GUID_REC_SIZE] ==
660				cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL))
661			delete_guid_indexes |=
662				mlx4_ib_get_aguid_comp_mask_from_ix(i);
663		else
664			set_guid_indexes |=
665				mlx4_ib_get_aguid_comp_mask_from_ix(i);
666
667		if (lowset_time_entry == -1 || rec->guids_retry_schedule[i] <=
668			lowest_time) {
669			lowset_time_entry = i;
670			lowest_time = rec->guids_retry_schedule[i];
671		}
672	}
673
674	memcpy(&next_rec->rec_det, rec, sizeof(*rec));
675	next_rec->port = port;
676	next_rec->block_num = record_index;
677
678	if (*(__be64 *)&rec->all_recs[lowset_time_entry * GUID_REC_SIZE] ==
679				cpu_to_be64(MLX4_GUID_FOR_DELETE_VAL)) {
680		next_rec->rec_det.guid_indexes = delete_guid_indexes;
681		next_rec->method = MLX4_GUID_INFO_RECORD_DELETE;
682	} else {
683		next_rec->rec_det.guid_indexes = set_guid_indexes;
684		next_rec->method = MLX4_GUID_INFO_RECORD_SET;
685	}
686}
687
688/* return index of record that should be updated based on lowest
689 * rescheduled time
690 */
691static int get_low_record_time_index(struct mlx4_ib_dev *dev, u8 port,
692				     int *resched_delay_sec)
693{
694	int record_index = -1;
695	u64 low_record_time = 0;
696	struct mlx4_sriov_alias_guid_info_rec_det rec;
697	int j;
698
699	for (j = 0; j < NUM_ALIAS_GUID_REC_IN_PORT; j++) {
700		rec = dev->sriov.alias_guid.ports_guid[port].
701			all_rec_per_port[j];
702		if (rec.status == MLX4_GUID_INFO_STATUS_IDLE &&
703		    rec.guid_indexes) {
704			if (record_index == -1 ||
705			    rec.time_to_run < low_record_time) {
706				record_index = j;
707				low_record_time = rec.time_to_run;
708			}
709		}
710	}
711	if (resched_delay_sec) {
712		u64 curr_time = ktime_get_boottime_ns();
713
714		*resched_delay_sec = (low_record_time < curr_time) ? 0 :
715			div_u64((low_record_time - curr_time), NSEC_PER_SEC);
716	}
717
718	return record_index;
719}
720
721/* The function returns the next record that was
722 * not configured (or failed to be configured) */
723static int get_next_record_to_update(struct mlx4_ib_dev *dev, u8 port,
724				     struct mlx4_next_alias_guid_work *rec)
725{
726	unsigned long flags;
727	int record_index;
728	int ret = 0;
729
730	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags);
731	record_index = get_low_record_time_index(dev, port, NULL);
732
733	if (record_index < 0) {
734		ret = -ENOENT;
735		goto out;
736	}
737
738	set_required_record(dev, port, rec, record_index);
739out:
740	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags);
741	return ret;
742}
743
744static void alias_guid_work(struct work_struct *work)
745{
746	struct delayed_work *delay = to_delayed_work(work);
747	int ret = 0;
748	struct mlx4_next_alias_guid_work *rec;
749	struct mlx4_sriov_alias_guid_port_rec_det *sriov_alias_port =
750		container_of(delay, struct mlx4_sriov_alias_guid_port_rec_det,
751			     alias_guid_work);
752	struct mlx4_sriov_alias_guid *sriov_alias_guid = sriov_alias_port->parent;
753	struct mlx4_ib_sriov *ib_sriov = container_of(sriov_alias_guid,
754						struct mlx4_ib_sriov,
755						alias_guid);
756	struct mlx4_ib_dev *dev = container_of(ib_sriov, struct mlx4_ib_dev, sriov);
757
758	rec = kzalloc(sizeof *rec, GFP_KERNEL);
759	if (!rec)
760		return;
761
762	pr_debug("starting [port: %d]...\n", sriov_alias_port->port + 1);
763	ret = get_next_record_to_update(dev, sriov_alias_port->port, rec);
764	if (ret) {
765		pr_debug("No more records to update.\n");
766		goto out;
767	}
768
769	set_guid_rec(&dev->ib_dev, rec);
770out:
771	kfree(rec);
772}
773
774
775void mlx4_ib_init_alias_guid_work(struct mlx4_ib_dev *dev, int port)
776{
777	unsigned long flags, flags1;
778
779	if (!mlx4_is_master(dev->dev))
780		return;
781	spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
782	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
783	if (!dev->sriov.is_going_down) {
784		/* If there is pending one should cancel then run, otherwise
785		  * won't run till previous one is ended as same work
786		  * struct is used.
787		  */
788		cancel_delayed_work(&dev->sriov.alias_guid.ports_guid[port].
789				    alias_guid_work);
790		queue_delayed_work(dev->sriov.alias_guid.ports_guid[port].wq,
791			   &dev->sriov.alias_guid.ports_guid[port].alias_guid_work, 0);
792	}
793	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
794	spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
795}
796
797void mlx4_ib_destroy_alias_guid_service(struct mlx4_ib_dev *dev)
798{
799	int i;
800	struct mlx4_ib_sriov *sriov = &dev->sriov;
801	struct mlx4_alias_guid_work_context *cb_ctx;
802	struct mlx4_sriov_alias_guid_port_rec_det *det;
803	struct ib_sa_query *sa_query;
804	unsigned long flags;
805
806	for (i = 0 ; i < dev->num_ports; i++) {
807		det = &sriov->alias_guid.ports_guid[i];
808		cancel_delayed_work_sync(&det->alias_guid_work);
809		spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags);
810		while (!list_empty(&det->cb_list)) {
811			cb_ctx = list_entry(det->cb_list.next,
812					    struct mlx4_alias_guid_work_context,
813					    list);
814			sa_query = cb_ctx->sa_query;
815			cb_ctx->sa_query = NULL;
816			list_del(&cb_ctx->list);
817			spin_unlock_irqrestore(&sriov->alias_guid.ag_work_lock, flags);
818			ib_sa_cancel_query(cb_ctx->query_id, sa_query);
819			wait_for_completion(&cb_ctx->done);
820			kfree(cb_ctx);
821			spin_lock_irqsave(&sriov->alias_guid.ag_work_lock, flags);
822		}
823		spin_unlock_irqrestore(&sriov->alias_guid.ag_work_lock, flags);
824	}
825	for (i = 0 ; i < dev->num_ports; i++) {
826		flush_workqueue(dev->sriov.alias_guid.ports_guid[i].wq);
827		destroy_workqueue(dev->sriov.alias_guid.ports_guid[i].wq);
828	}
829	ib_sa_unregister_client(dev->sriov.alias_guid.sa_client);
830	kfree(dev->sriov.alias_guid.sa_client);
831}
832
833int mlx4_ib_init_alias_guid_service(struct mlx4_ib_dev *dev)
834{
835	char alias_wq_name[15];
836	int ret = 0;
837	int i, j;
838	union ib_gid gid;
839
840	if (!mlx4_is_master(dev->dev))
841		return 0;
842	dev->sriov.alias_guid.sa_client =
843		kzalloc(sizeof *dev->sriov.alias_guid.sa_client, GFP_KERNEL);
844	if (!dev->sriov.alias_guid.sa_client)
845		return -ENOMEM;
846
847	ib_sa_register_client(dev->sriov.alias_guid.sa_client);
848
849	spin_lock_init(&dev->sriov.alias_guid.ag_work_lock);
850
851	for (i = 1; i <= dev->num_ports; ++i) {
852		if (dev->ib_dev.ops.query_gid(&dev->ib_dev, i, 0, &gid)) {
853			ret = -EFAULT;
854			goto err_unregister;
855		}
856	}
857
858	for (i = 0 ; i < dev->num_ports; i++) {
859		memset(&dev->sriov.alias_guid.ports_guid[i], 0,
860		       sizeof (struct mlx4_sriov_alias_guid_port_rec_det));
861		dev->sriov.alias_guid.ports_guid[i].state_flags |=
862				GUID_STATE_NEED_PORT_INIT;
863		for (j = 0; j < NUM_ALIAS_GUID_REC_IN_PORT; j++) {
864			/* mark each val as it was deleted */
865			memset(dev->sriov.alias_guid.ports_guid[i].
866				all_rec_per_port[j].all_recs, 0xFF,
867				sizeof(dev->sriov.alias_guid.ports_guid[i].
868				all_rec_per_port[j].all_recs));
869		}
870		INIT_LIST_HEAD(&dev->sriov.alias_guid.ports_guid[i].cb_list);
871		/*prepare the records, set them to be allocated by sm*/
872		if (mlx4_ib_sm_guid_assign)
873			for (j = 1; j < NUM_ALIAS_GUID_PER_PORT; j++)
874				mlx4_set_admin_guid(dev->dev, 0, j, i + 1);
875		for (j = 0 ; j < NUM_ALIAS_GUID_REC_IN_PORT; j++)
876			invalidate_guid_record(dev, i + 1, j);
877
878		dev->sriov.alias_guid.ports_guid[i].parent = &dev->sriov.alias_guid;
879		dev->sriov.alias_guid.ports_guid[i].port  = i;
880
881		snprintf(alias_wq_name, sizeof alias_wq_name, "alias_guid%d", i);
882		dev->sriov.alias_guid.ports_guid[i].wq =
883			alloc_ordered_workqueue(alias_wq_name, WQ_MEM_RECLAIM);
884		if (!dev->sriov.alias_guid.ports_guid[i].wq) {
885			ret = -ENOMEM;
886			goto err_thread;
887		}
888		INIT_DELAYED_WORK(&dev->sriov.alias_guid.ports_guid[i].alias_guid_work,
889			  alias_guid_work);
890	}
891	return 0;
892
893err_thread:
894	for (--i; i >= 0; i--) {
895		destroy_workqueue(dev->sriov.alias_guid.ports_guid[i].wq);
896		dev->sriov.alias_guid.ports_guid[i].wq = NULL;
897	}
898
899err_unregister:
900	ib_sa_unregister_client(dev->sriov.alias_guid.sa_client);
901	kfree(dev->sriov.alias_guid.sa_client);
902	dev->sriov.alias_guid.sa_client = NULL;
903	pr_err("init_alias_guid_service: Failed. (ret:%d)\n", ret);
904	return ret;
905}