xref: /linux/drivers/scsi/snic/vnic_dev.c (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright 2014 Cisco Systems, Inc.  All rights reserved.
3 
4 #include <linux/kernel.h>
5 #include <linux/errno.h>
6 #include <linux/types.h>
7 #include <linux/pci.h>
8 #include <linux/delay.h>
9 #include <linux/if_ether.h>
10 #include <linux/slab.h>
11 #include "vnic_resource.h"
12 #include "vnic_devcmd.h"
13 #include "vnic_dev.h"
14 #include "vnic_stats.h"
15 #include "vnic_wq.h"
16 
17 #define VNIC_DVCMD_TMO	10000	/* Devcmd Timeout value */
18 #define VNIC_NOTIFY_INTR_MASK 0x0000ffff00000000ULL
19 
20 struct devcmd2_controller {
21 	struct vnic_wq_ctrl __iomem *wq_ctrl;
22 	struct vnic_dev_ring results_ring;
23 	struct vnic_wq wq;
24 	struct vnic_devcmd2 *cmd_ring;
25 	struct devcmd2_result *result;
26 	u16 next_result;
27 	u16 result_size;
28 	int color;
29 };
30 
31 struct vnic_res {
32 	void __iomem *vaddr;
33 	unsigned int count;
34 };
35 
36 struct vnic_dev {
37 	void *priv;
38 	struct pci_dev *pdev;
39 	struct vnic_res res[RES_TYPE_MAX];
40 	enum vnic_dev_intr_mode intr_mode;
41 	struct vnic_devcmd __iomem *devcmd;
42 	struct vnic_devcmd_notify *notify;
43 	struct vnic_devcmd_notify notify_copy;
44 	dma_addr_t notify_pa;
45 	struct vnic_stats *stats;
46 	dma_addr_t stats_pa;
47 	struct vnic_devcmd_fw_info *fw_info;
48 	dma_addr_t fw_info_pa;
49 	u64 args[VNIC_DEVCMD_NARGS];
50 	struct devcmd2_controller *devcmd2;
51 
52 	int (*devcmd_rtn)(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
53 			  int wait);
54 };
55 
56 #define VNIC_MAX_RES_HDR_SIZE \
57 	(sizeof(struct vnic_resource_header) + \
58 	sizeof(struct vnic_resource) * RES_TYPE_MAX)
59 #define VNIC_RES_STRIDE	128
60 
61 void *svnic_dev_priv(struct vnic_dev *vdev)
62 {
63 	return vdev->priv;
64 }
65 
66 static int vnic_dev_discover_res(struct vnic_dev *vdev,
67 	struct vnic_dev_bar *bar, unsigned int num_bars)
68 {
69 	struct vnic_resource_header __iomem *rh;
70 	struct vnic_resource __iomem *r;
71 	u8 type;
72 
73 	if (num_bars == 0)
74 		return -EINVAL;
75 
76 	if (bar->len < VNIC_MAX_RES_HDR_SIZE) {
77 		pr_err("vNIC BAR0 res hdr length error\n");
78 
79 		return -EINVAL;
80 	}
81 
82 	rh = bar->vaddr;
83 	if (!rh) {
84 		pr_err("vNIC BAR0 res hdr not mem-mapped\n");
85 
86 		return -EINVAL;
87 	}
88 
89 	if (ioread32(&rh->magic) != VNIC_RES_MAGIC ||
90 	    ioread32(&rh->version) != VNIC_RES_VERSION) {
91 		pr_err("vNIC BAR0 res magic/version error exp (%lx/%lx) curr (%x/%x)\n",
92 			VNIC_RES_MAGIC, VNIC_RES_VERSION,
93 			ioread32(&rh->magic), ioread32(&rh->version));
94 
95 		return -EINVAL;
96 	}
97 
98 	r = (struct vnic_resource __iomem *)(rh + 1);
99 
100 	while ((type = ioread8(&r->type)) != RES_TYPE_EOL) {
101 
102 		u8 bar_num = ioread8(&r->bar);
103 		u32 bar_offset = ioread32(&r->bar_offset);
104 		u32 count = ioread32(&r->count);
105 		u32 len;
106 
107 		r++;
108 
109 		if (bar_num >= num_bars)
110 			continue;
111 
112 		if (!bar[bar_num].len || !bar[bar_num].vaddr)
113 			continue;
114 
115 		switch (type) {
116 		case RES_TYPE_WQ:
117 		case RES_TYPE_RQ:
118 		case RES_TYPE_CQ:
119 		case RES_TYPE_INTR_CTRL:
120 			/* each count is stride bytes long */
121 			len = count * VNIC_RES_STRIDE;
122 			if (len + bar_offset > bar->len) {
123 				pr_err("vNIC BAR0 resource %d out-of-bounds, offset 0x%x + size 0x%x > bar len 0x%lx\n",
124 					type, bar_offset,
125 					len,
126 					bar->len);
127 
128 				return -EINVAL;
129 			}
130 			break;
131 
132 		case RES_TYPE_INTR_PBA_LEGACY:
133 		case RES_TYPE_DEVCMD:
134 		case RES_TYPE_DEVCMD2:
135 			break;
136 
137 		default:
138 			continue;
139 		}
140 
141 		vdev->res[type].count = count;
142 		vdev->res[type].vaddr = (char __iomem *)bar->vaddr + bar_offset;
143 	}
144 
145 	return 0;
146 }
147 
148 unsigned int svnic_dev_get_res_count(struct vnic_dev *vdev,
149 	enum vnic_res_type type)
150 {
151 	return vdev->res[type].count;
152 }
153 
154 void __iomem *svnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
155 	unsigned int index)
156 {
157 	if (!vdev->res[type].vaddr)
158 		return NULL;
159 
160 	switch (type) {
161 	case RES_TYPE_WQ:
162 	case RES_TYPE_RQ:
163 	case RES_TYPE_CQ:
164 	case RES_TYPE_INTR_CTRL:
165 		return (char __iomem *)vdev->res[type].vaddr +
166 					index * VNIC_RES_STRIDE;
167 
168 	default:
169 		return (char __iomem *)vdev->res[type].vaddr;
170 	}
171 }
172 
173 unsigned int svnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
174 				      unsigned int desc_count,
175 				      unsigned int desc_size)
176 {
177 	/* The base address of the desc rings must be 512 byte aligned.
178 	 * Descriptor count is aligned to groups of 32 descriptors.  A
179 	 * count of 0 means the maximum 4096 descriptors.  Descriptor
180 	 * size is aligned to 16 bytes.
181 	 */
182 
183 	unsigned int count_align = 32;
184 	unsigned int desc_align = 16;
185 
186 	ring->base_align = 512;
187 
188 	if (desc_count == 0)
189 		desc_count = 4096;
190 
191 	ring->desc_count = ALIGN(desc_count, count_align);
192 
193 	ring->desc_size = ALIGN(desc_size, desc_align);
194 
195 	ring->size = ring->desc_count * ring->desc_size;
196 	ring->size_unaligned = ring->size + ring->base_align;
197 
198 	return ring->size_unaligned;
199 }
200 
201 void svnic_dev_clear_desc_ring(struct vnic_dev_ring *ring)
202 {
203 	memset(ring->descs, 0, ring->size);
204 }
205 
206 int svnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,
207 	unsigned int desc_count, unsigned int desc_size)
208 {
209 	svnic_dev_desc_ring_size(ring, desc_count, desc_size);
210 
211 	ring->descs_unaligned = dma_alloc_coherent(&vdev->pdev->dev,
212 			ring->size_unaligned, &ring->base_addr_unaligned,
213 			GFP_KERNEL);
214 	if (!ring->descs_unaligned) {
215 		pr_err("Failed to allocate ring (size=%d), aborting\n",
216 			(int)ring->size);
217 
218 		return -ENOMEM;
219 	}
220 
221 	ring->base_addr = ALIGN(ring->base_addr_unaligned,
222 		ring->base_align);
223 	ring->descs = (u8 *)ring->descs_unaligned +
224 		(ring->base_addr - ring->base_addr_unaligned);
225 
226 	svnic_dev_clear_desc_ring(ring);
227 
228 	ring->desc_avail = ring->desc_count - 1;
229 
230 	return 0;
231 }
232 
233 void svnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring)
234 {
235 	if (ring->descs) {
236 		dma_free_coherent(&vdev->pdev->dev,
237 			ring->size_unaligned,
238 			ring->descs_unaligned,
239 			ring->base_addr_unaligned);
240 		ring->descs = NULL;
241 	}
242 }
243 
244 static int _svnic_dev_cmd2(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
245 	int wait)
246 {
247 	struct devcmd2_controller *dc2c = vdev->devcmd2;
248 	struct devcmd2_result *result = NULL;
249 	unsigned int i;
250 	int delay;
251 	int err;
252 	u32 posted;
253 	u32 fetch_idx;
254 	u32 new_posted;
255 	u8 color;
256 
257 	fetch_idx = ioread32(&dc2c->wq_ctrl->fetch_index);
258 	if (fetch_idx == 0xFFFFFFFF) { /* check for hardware gone  */
259 		/* Hardware surprise removal: return error */
260 		return -ENODEV;
261 	}
262 
263 	posted = ioread32(&dc2c->wq_ctrl->posted_index);
264 
265 	if (posted == 0xFFFFFFFF) { /* check for hardware gone  */
266 		/* Hardware surprise removal: return error */
267 		return -ENODEV;
268 	}
269 
270 	new_posted = (posted + 1) % DEVCMD2_RING_SIZE;
271 	if (new_posted == fetch_idx) {
272 		pr_err("%s: wq is full while issuing devcmd2 command %d, fetch index: %u, posted index: %u\n",
273 			pci_name(vdev->pdev), _CMD_N(cmd), fetch_idx, posted);
274 
275 		return -EBUSY;
276 	}
277 
278 	dc2c->cmd_ring[posted].cmd = cmd;
279 	dc2c->cmd_ring[posted].flags = 0;
280 
281 	if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT))
282 		dc2c->cmd_ring[posted].flags |= DEVCMD2_FNORESULT;
283 
284 	if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) {
285 		for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
286 			dc2c->cmd_ring[posted].args[i] = vdev->args[i];
287 	}
288 	/* Adding write memory barrier prevents compiler and/or CPU
289 	 * reordering, thus avoiding descriptor posting before
290 	 * descriptor is initialized. Otherwise, hardware can read
291 	 * stale descriptor fields.
292 	 */
293 	wmb();
294 	iowrite32(new_posted, &dc2c->wq_ctrl->posted_index);
295 
296 	if (dc2c->cmd_ring[posted].flags & DEVCMD2_FNORESULT)
297 		return 0;
298 
299 	result = dc2c->result + dc2c->next_result;
300 	color = dc2c->color;
301 
302 	/*
303 	 * Increment next_result, after posting the devcmd, irrespective of
304 	 * devcmd result, and it should be done only once.
305 	 */
306 	dc2c->next_result++;
307 	if (dc2c->next_result == dc2c->result_size) {
308 		dc2c->next_result = 0;
309 		dc2c->color = dc2c->color ? 0 : 1;
310 	}
311 
312 	for (delay = 0; delay < wait; delay++) {
313 		udelay(100);
314 		if (result->color == color) {
315 			if (result->error) {
316 				err = (int) result->error;
317 				if (err != ERR_ECMDUNKNOWN ||
318 				    cmd != CMD_CAPABILITY)
319 					pr_err("Error %d devcmd %d\n",
320 						err, _CMD_N(cmd));
321 
322 				return err;
323 			}
324 			if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
325 				for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
326 					vdev->args[i] = result->results[i];
327 			}
328 
329 			return 0;
330 		}
331 	}
332 
333 	pr_err("Timed out devcmd %d\n", _CMD_N(cmd));
334 
335 	return -ETIMEDOUT;
336 }
337 
338 static int svnic_dev_init_devcmd2(struct vnic_dev *vdev)
339 {
340 	struct devcmd2_controller *dc2c = NULL;
341 	unsigned int fetch_idx;
342 	int ret;
343 	void __iomem *p;
344 
345 	if (vdev->devcmd2)
346 		return 0;
347 
348 	p = svnic_dev_get_res(vdev, RES_TYPE_DEVCMD2, 0);
349 	if (!p)
350 		return -ENODEV;
351 
352 	dc2c = kzalloc_obj(*dc2c, GFP_ATOMIC);
353 	if (!dc2c)
354 		return -ENOMEM;
355 
356 	vdev->devcmd2 = dc2c;
357 
358 	dc2c->color = 1;
359 	dc2c->result_size = DEVCMD2_RING_SIZE;
360 
361 	ret  = vnic_wq_devcmd2_alloc(vdev,
362 				     &dc2c->wq,
363 				     DEVCMD2_RING_SIZE,
364 				     DEVCMD2_DESC_SIZE);
365 	if (ret)
366 		goto err_free_devcmd2;
367 
368 	fetch_idx = ioread32(&dc2c->wq.ctrl->fetch_index);
369 	if (fetch_idx == 0xFFFFFFFF) { /* check for hardware gone  */
370 		/* Hardware surprise removal: reset fetch_index */
371 		fetch_idx = 0;
372 	}
373 
374 	/*
375 	 * Don't change fetch_index ever and
376 	 * set posted_index same as fetch_index
377 	 * when setting up the WQ for devcmd2.
378 	 */
379 	vnic_wq_init_start(&dc2c->wq, 0, fetch_idx, fetch_idx, 0, 0);
380 	svnic_wq_enable(&dc2c->wq);
381 	ret = svnic_dev_alloc_desc_ring(vdev,
382 					&dc2c->results_ring,
383 					DEVCMD2_RING_SIZE,
384 					DEVCMD2_DESC_SIZE);
385 	if (ret)
386 		goto err_free_wq;
387 
388 	dc2c->result = (struct devcmd2_result *) dc2c->results_ring.descs;
389 	dc2c->cmd_ring = (struct vnic_devcmd2 *) dc2c->wq.ring.descs;
390 	dc2c->wq_ctrl = dc2c->wq.ctrl;
391 	vdev->args[0] = (u64) dc2c->results_ring.base_addr | VNIC_PADDR_TARGET;
392 	vdev->args[1] = DEVCMD2_RING_SIZE;
393 
394 	ret = _svnic_dev_cmd2(vdev, CMD_INITIALIZE_DEVCMD2, VNIC_DVCMD_TMO);
395 	if (ret < 0)
396 		goto err_free_desc_ring;
397 
398 	vdev->devcmd_rtn = &_svnic_dev_cmd2;
399 	pr_info("DEVCMD2 Initialized.\n");
400 
401 	return ret;
402 
403 err_free_desc_ring:
404 	svnic_dev_free_desc_ring(vdev, &dc2c->results_ring);
405 
406 err_free_wq:
407 	svnic_wq_disable(&dc2c->wq);
408 	svnic_wq_free(&dc2c->wq);
409 
410 err_free_devcmd2:
411 	kfree(dc2c);
412 	vdev->devcmd2 = NULL;
413 
414 	return ret;
415 } /* end of svnic_dev_init_devcmd2 */
416 
417 static void vnic_dev_deinit_devcmd2(struct vnic_dev *vdev)
418 {
419 	struct devcmd2_controller *dc2c = vdev->devcmd2;
420 
421 	vdev->devcmd2 = NULL;
422 	vdev->devcmd_rtn = NULL;
423 
424 	svnic_dev_free_desc_ring(vdev, &dc2c->results_ring);
425 	svnic_wq_disable(&dc2c->wq);
426 	svnic_wq_free(&dc2c->wq);
427 	kfree(dc2c);
428 }
429 
430 int svnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
431 	u64 *a0, u64 *a1, int wait)
432 {
433 	int err;
434 
435 	memset(vdev->args, 0, sizeof(vdev->args));
436 	vdev->args[0] = *a0;
437 	vdev->args[1] = *a1;
438 
439 	err = (*vdev->devcmd_rtn)(vdev, cmd, wait);
440 
441 	*a0 = vdev->args[0];
442 	*a1 = vdev->args[1];
443 
444 	return  err;
445 }
446 
447 int svnic_dev_fw_info(struct vnic_dev *vdev,
448 	struct vnic_devcmd_fw_info **fw_info)
449 {
450 	u64 a0, a1 = 0;
451 	int wait = VNIC_DVCMD_TMO;
452 	int err = 0;
453 
454 	if (!vdev->fw_info) {
455 		vdev->fw_info = dma_alloc_coherent(&vdev->pdev->dev,
456 			sizeof(struct vnic_devcmd_fw_info),
457 			&vdev->fw_info_pa, GFP_KERNEL);
458 		if (!vdev->fw_info)
459 			return -ENOMEM;
460 
461 		a0 = vdev->fw_info_pa;
462 
463 		/* only get fw_info once and cache it */
464 		err = svnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait);
465 	}
466 
467 	*fw_info = vdev->fw_info;
468 
469 	return err;
470 }
471 
472 int svnic_dev_spec(struct vnic_dev *vdev, unsigned int offset,
473 	unsigned int size, void *value)
474 {
475 	u64 a0, a1;
476 	int wait = VNIC_DVCMD_TMO;
477 	int err;
478 
479 	a0 = offset;
480 	a1 = size;
481 
482 	err = svnic_dev_cmd(vdev, CMD_DEV_SPEC, &a0, &a1, wait);
483 
484 	switch (size) {
485 	case 1:
486 		*(u8 *)value = (u8)a0;
487 		break;
488 	case 2:
489 		*(u16 *)value = (u16)a0;
490 		break;
491 	case 4:
492 		*(u32 *)value = (u32)a0;
493 		break;
494 	case 8:
495 		*(u64 *)value = a0;
496 		break;
497 	default:
498 		BUG();
499 		break;
500 	}
501 
502 	return err;
503 }
504 
505 int svnic_dev_stats_clear(struct vnic_dev *vdev)
506 {
507 	u64 a0 = 0, a1 = 0;
508 	int wait = VNIC_DVCMD_TMO;
509 
510 	return svnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait);
511 }
512 
513 int svnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)
514 {
515 	u64 a0, a1;
516 	int wait = VNIC_DVCMD_TMO;
517 
518 	if (!vdev->stats) {
519 		vdev->stats = dma_alloc_coherent(&vdev->pdev->dev,
520 			sizeof(struct vnic_stats), &vdev->stats_pa, GFP_KERNEL);
521 		if (!vdev->stats)
522 			return -ENOMEM;
523 	}
524 
525 	*stats = vdev->stats;
526 	a0 = vdev->stats_pa;
527 	a1 = sizeof(struct vnic_stats);
528 
529 	return svnic_dev_cmd(vdev, CMD_STATS_DUMP, &a0, &a1, wait);
530 }
531 
532 int svnic_dev_close(struct vnic_dev *vdev)
533 {
534 	u64 a0 = 0, a1 = 0;
535 	int wait = VNIC_DVCMD_TMO;
536 
537 	return svnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait);
538 }
539 
540 int svnic_dev_enable_wait(struct vnic_dev *vdev)
541 {
542 	u64 a0 = 0, a1 = 0;
543 	int wait = VNIC_DVCMD_TMO;
544 	int err = 0;
545 
546 	err = svnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait);
547 	if (err == ERR_ECMDUNKNOWN)
548 		return svnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);
549 
550 	return err;
551 }
552 
553 int svnic_dev_disable(struct vnic_dev *vdev)
554 {
555 	u64 a0 = 0, a1 = 0;
556 	int wait = VNIC_DVCMD_TMO;
557 
558 	return svnic_dev_cmd(vdev, CMD_DISABLE, &a0, &a1, wait);
559 }
560 
561 int svnic_dev_open(struct vnic_dev *vdev, int arg)
562 {
563 	u64 a0 = (u32)arg, a1 = 0;
564 	int wait = VNIC_DVCMD_TMO;
565 
566 	return svnic_dev_cmd(vdev, CMD_OPEN, &a0, &a1, wait);
567 }
568 
569 int svnic_dev_open_done(struct vnic_dev *vdev, int *done)
570 {
571 	u64 a0 = 0, a1 = 0;
572 	int wait = VNIC_DVCMD_TMO;
573 	int err;
574 
575 	*done = 0;
576 
577 	err = svnic_dev_cmd(vdev, CMD_OPEN_STATUS, &a0, &a1, wait);
578 	if (err)
579 		return err;
580 
581 	*done = (a0 == 0);
582 
583 	return 0;
584 }
585 
586 int svnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
587 {
588 	u64 a0, a1;
589 	int wait = VNIC_DVCMD_TMO;
590 
591 	if (!vdev->notify) {
592 		vdev->notify = dma_alloc_coherent(&vdev->pdev->dev,
593 			sizeof(struct vnic_devcmd_notify),
594 			&vdev->notify_pa, GFP_KERNEL);
595 		if (!vdev->notify)
596 			return -ENOMEM;
597 	}
598 
599 	a0 = vdev->notify_pa;
600 	a1 = ((u64)intr << 32) & VNIC_NOTIFY_INTR_MASK;
601 	a1 += sizeof(struct vnic_devcmd_notify);
602 
603 	return svnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
604 }
605 
606 void svnic_dev_notify_unset(struct vnic_dev *vdev)
607 {
608 	u64 a0, a1;
609 	int wait = VNIC_DVCMD_TMO;
610 
611 	a0 = 0;  /* paddr = 0 to unset notify buffer */
612 	a1 = VNIC_NOTIFY_INTR_MASK; /* intr num = -1 to unreg for intr */
613 	a1 += sizeof(struct vnic_devcmd_notify);
614 
615 	svnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
616 }
617 
618 static int vnic_dev_notify_ready(struct vnic_dev *vdev)
619 {
620 	u32 *words;
621 	unsigned int nwords = sizeof(struct vnic_devcmd_notify) / 4;
622 	unsigned int i;
623 	u32 csum;
624 
625 	if (!vdev->notify)
626 		return 0;
627 
628 	do {
629 		csum = 0;
630 		memcpy(&vdev->notify_copy, vdev->notify,
631 			sizeof(struct vnic_devcmd_notify));
632 		words = (u32 *)&vdev->notify_copy;
633 		for (i = 1; i < nwords; i++)
634 			csum += words[i];
635 	} while (csum != words[0]);
636 
637 	return 1;
638 }
639 
640 int svnic_dev_init(struct vnic_dev *vdev, int arg)
641 {
642 	u64 a0 = (u32)arg, a1 = 0;
643 	int wait = VNIC_DVCMD_TMO;
644 
645 	return svnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
646 }
647 
648 int svnic_dev_link_status(struct vnic_dev *vdev)
649 {
650 
651 	if (!vnic_dev_notify_ready(vdev))
652 		return 0;
653 
654 	return vdev->notify_copy.link_state;
655 }
656 
657 u32 svnic_dev_link_down_cnt(struct vnic_dev *vdev)
658 {
659 	if (!vnic_dev_notify_ready(vdev))
660 		return 0;
661 
662 	return vdev->notify_copy.link_down_cnt;
663 }
664 
665 void svnic_dev_set_intr_mode(struct vnic_dev *vdev,
666 	enum vnic_dev_intr_mode intr_mode)
667 {
668 	vdev->intr_mode = intr_mode;
669 }
670 
671 enum vnic_dev_intr_mode svnic_dev_get_intr_mode(struct vnic_dev *vdev)
672 {
673 	return vdev->intr_mode;
674 }
675 
676 void svnic_dev_unregister(struct vnic_dev *vdev)
677 {
678 	if (vdev) {
679 		if (vdev->notify)
680 			dma_free_coherent(&vdev->pdev->dev,
681 				sizeof(struct vnic_devcmd_notify),
682 				vdev->notify,
683 				vdev->notify_pa);
684 		if (vdev->stats)
685 			dma_free_coherent(&vdev->pdev->dev,
686 				sizeof(struct vnic_stats),
687 				vdev->stats, vdev->stats_pa);
688 		if (vdev->fw_info)
689 			dma_free_coherent(&vdev->pdev->dev,
690 				sizeof(struct vnic_devcmd_fw_info),
691 				vdev->fw_info, vdev->fw_info_pa);
692 		if (vdev->devcmd2)
693 			vnic_dev_deinit_devcmd2(vdev);
694 		kfree(vdev);
695 	}
696 }
697 
698 struct vnic_dev *svnic_dev_alloc_discover(struct vnic_dev *vdev,
699 					  void *priv,
700 					  struct pci_dev *pdev,
701 					  struct vnic_dev_bar *bar,
702 					  unsigned int num_bars)
703 {
704 	if (!vdev) {
705 		vdev = kzalloc_obj(struct vnic_dev, GFP_ATOMIC);
706 		if (!vdev)
707 			return NULL;
708 	}
709 
710 	vdev->priv = priv;
711 	vdev->pdev = pdev;
712 
713 	if (vnic_dev_discover_res(vdev, bar, num_bars))
714 		goto err_out;
715 
716 	return vdev;
717 
718 err_out:
719 	svnic_dev_unregister(vdev);
720 
721 	return NULL;
722 } /* end of svnic_dev_alloc_discover */
723 
724 /*
725  * fallback option is left to keep the interface common for other vnics.
726  */
727 int svnic_dev_cmd_init(struct vnic_dev *vdev, int fallback)
728 {
729 	int err = -ENODEV;
730 	void __iomem *p;
731 
732 	p = svnic_dev_get_res(vdev, RES_TYPE_DEVCMD2, 0);
733 	if (p)
734 		err = svnic_dev_init_devcmd2(vdev);
735 	else
736 		pr_err("DEVCMD2 resource not found.\n");
737 
738 	return err;
739 } /* end of svnic_dev_cmd_init */
740