Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
[sfrench/cifs-2.6.git] / drivers / net / enic / vnic_dev.c
1 /*
2  * Copyright 2008 Cisco Systems, Inc.  All rights reserved.
3  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
4  *
5  * This program is free software; you may redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; version 2 of the License.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
10  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
13  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
15  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16  * SOFTWARE.
17  *
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/types.h>
23 #include <linux/pci.h>
24 #include <linux/delay.h>
25 #include <linux/if_ether.h>
26
27 #include "vnic_resource.h"
28 #include "vnic_devcmd.h"
29 #include "vnic_dev.h"
30 #include "vnic_stats.h"
31
32 struct vnic_res {
33         void __iomem *vaddr;
34         dma_addr_t bus_addr;
35         unsigned int count;
36 };
37
38 #define VNIC_DEV_CAP_INIT       0x0001
39
40 struct vnic_dev {
41         void *priv;
42         struct pci_dev *pdev;
43         struct vnic_res res[RES_TYPE_MAX];
44         enum vnic_dev_intr_mode intr_mode;
45         struct vnic_devcmd __iomem *devcmd;
46         struct vnic_devcmd_notify *notify;
47         struct vnic_devcmd_notify notify_copy;
48         dma_addr_t notify_pa;
49         u32 notify_sz;
50         u32 *linkstatus;
51         dma_addr_t linkstatus_pa;
52         struct vnic_stats *stats;
53         dma_addr_t stats_pa;
54         struct vnic_devcmd_fw_info *fw_info;
55         dma_addr_t fw_info_pa;
56         u32 cap_flags;
57 };
58
59 #define VNIC_MAX_RES_HDR_SIZE \
60         (sizeof(struct vnic_resource_header) + \
61         sizeof(struct vnic_resource) * RES_TYPE_MAX)
62 #define VNIC_RES_STRIDE 128
63
64 void *vnic_dev_priv(struct vnic_dev *vdev)
65 {
66         return vdev->priv;
67 }
68
69 static int vnic_dev_discover_res(struct vnic_dev *vdev,
70         struct vnic_dev_bar *bar, unsigned int num_bars)
71 {
72         struct vnic_resource_header __iomem *rh;
73         struct vnic_resource __iomem *r;
74         u8 type;
75
76         if (num_bars == 0)
77                 return -EINVAL;
78
79         if (bar->len < VNIC_MAX_RES_HDR_SIZE) {
80                 printk(KERN_ERR "vNIC BAR0 res hdr length error\n");
81                 return -EINVAL;
82         }
83
84         rh = bar->vaddr;
85         if (!rh) {
86                 printk(KERN_ERR "vNIC BAR0 res hdr not mem-mapped\n");
87                 return -EINVAL;
88         }
89
90         if (ioread32(&rh->magic) != VNIC_RES_MAGIC ||
91             ioread32(&rh->version) != VNIC_RES_VERSION) {
92                 printk(KERN_ERR "vNIC BAR0 res magic/version error "
93                         "exp (%lx/%lx) curr (%x/%x)\n",
94                         VNIC_RES_MAGIC, VNIC_RES_VERSION,
95                         ioread32(&rh->magic), ioread32(&rh->version));
96                 return -EINVAL;
97         }
98
99         r = (struct vnic_resource __iomem *)(rh + 1);
100
101         while ((type = ioread8(&r->type)) != RES_TYPE_EOL) {
102
103                 u8 bar_num = ioread8(&r->bar);
104                 u32 bar_offset = ioread32(&r->bar_offset);
105                 u32 count = ioread32(&r->count);
106                 u32 len;
107
108                 r++;
109
110                 if (bar_num >= num_bars)
111                         continue;
112
113                 if (!bar[bar_num].len || !bar[bar_num].vaddr)
114                         continue;
115
116                 switch (type) {
117                 case RES_TYPE_WQ:
118                 case RES_TYPE_RQ:
119                 case RES_TYPE_CQ:
120                 case RES_TYPE_INTR_CTRL:
121                         /* each count is stride bytes long */
122                         len = count * VNIC_RES_STRIDE;
123                         if (len + bar_offset > bar[bar_num].len) {
124                                 printk(KERN_ERR "vNIC BAR0 resource %d "
125                                         "out-of-bounds, offset 0x%x + "
126                                         "size 0x%x > bar len 0x%lx\n",
127                                         type, bar_offset,
128                                         len,
129                                         bar[bar_num].len);
130                                 return -EINVAL;
131                         }
132                         break;
133                 case RES_TYPE_INTR_PBA_LEGACY:
134                 case RES_TYPE_DEVCMD:
135                         len = count;
136                         break;
137                 default:
138                         continue;
139                 }
140
141                 vdev->res[type].count = count;
142                 vdev->res[type].vaddr = (char __iomem *)bar[bar_num].vaddr +
143                         bar_offset;
144                 vdev->res[type].bus_addr = bar[bar_num].bus_addr + bar_offset;
145         }
146
147         return 0;
148 }
149
150 unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,
151         enum vnic_res_type type)
152 {
153         return vdev->res[type].count;
154 }
155
156 void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
157         unsigned int index)
158 {
159         if (!vdev->res[type].vaddr)
160                 return NULL;
161
162         switch (type) {
163         case RES_TYPE_WQ:
164         case RES_TYPE_RQ:
165         case RES_TYPE_CQ:
166         case RES_TYPE_INTR_CTRL:
167                 return (char __iomem *)vdev->res[type].vaddr +
168                         index * VNIC_RES_STRIDE;
169         default:
170                 return (char __iomem *)vdev->res[type].vaddr;
171         }
172 }
173
174 dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev,
175         enum vnic_res_type type, unsigned int index)
176 {
177         switch (type) {
178         case RES_TYPE_WQ:
179         case RES_TYPE_RQ:
180         case RES_TYPE_CQ:
181         case RES_TYPE_INTR_CTRL:
182                 return vdev->res[type].bus_addr +
183                         index * VNIC_RES_STRIDE;
184         default:
185                 return vdev->res[type].bus_addr;
186         }
187 }
188
189 unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
190         unsigned int desc_count, unsigned int desc_size)
191 {
192         /* The base address of the desc rings must be 512 byte aligned.
193          * Descriptor count is aligned to groups of 32 descriptors.  A
194          * count of 0 means the maximum 4096 descriptors.  Descriptor
195          * size is aligned to 16 bytes.
196          */
197
198         unsigned int count_align = 32;
199         unsigned int desc_align = 16;
200
201         ring->base_align = 512;
202
203         if (desc_count == 0)
204                 desc_count = 4096;
205
206         ring->desc_count = ALIGN(desc_count, count_align);
207
208         ring->desc_size = ALIGN(desc_size, desc_align);
209
210         ring->size = ring->desc_count * ring->desc_size;
211         ring->size_unaligned = ring->size + ring->base_align;
212
213         return ring->size_unaligned;
214 }
215
216 void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring)
217 {
218         memset(ring->descs, 0, ring->size);
219 }
220
221 int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,
222         unsigned int desc_count, unsigned int desc_size)
223 {
224         vnic_dev_desc_ring_size(ring, desc_count, desc_size);
225
226         ring->descs_unaligned = pci_alloc_consistent(vdev->pdev,
227                 ring->size_unaligned,
228                 &ring->base_addr_unaligned);
229
230         if (!ring->descs_unaligned) {
231                 printk(KERN_ERR
232                   "Failed to allocate ring (size=%d), aborting\n",
233                         (int)ring->size);
234                 return -ENOMEM;
235         }
236
237         ring->base_addr = ALIGN(ring->base_addr_unaligned,
238                 ring->base_align);
239         ring->descs = (u8 *)ring->descs_unaligned +
240                 (ring->base_addr - ring->base_addr_unaligned);
241
242         vnic_dev_clear_desc_ring(ring);
243
244         ring->desc_avail = ring->desc_count - 1;
245
246         return 0;
247 }
248
249 void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring)
250 {
251         if (ring->descs) {
252                 pci_free_consistent(vdev->pdev,
253                         ring->size_unaligned,
254                         ring->descs_unaligned,
255                         ring->base_addr_unaligned);
256                 ring->descs = NULL;
257         }
258 }
259
260 int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
261         u64 *a0, u64 *a1, int wait)
262 {
263         struct vnic_devcmd __iomem *devcmd = vdev->devcmd;
264         int delay;
265         u32 status;
266         int err;
267
268         status = ioread32(&devcmd->status);
269         if (status & STAT_BUSY) {
270                 printk(KERN_ERR "Busy devcmd %d\n", _CMD_N(cmd));
271                 return -EBUSY;
272         }
273
274         if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) {
275                 writeq(*a0, &devcmd->args[0]);
276                 writeq(*a1, &devcmd->args[1]);
277                 wmb();
278         }
279
280         iowrite32(cmd, &devcmd->cmd);
281
282         if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT))
283                 return 0;
284
285         for (delay = 0; delay < wait; delay++) {
286
287                 udelay(100);
288
289                 status = ioread32(&devcmd->status);
290                 if (!(status & STAT_BUSY)) {
291
292                         if (status & STAT_ERROR) {
293                                 err = (int)readq(&devcmd->args[0]);
294                                 if (err != ERR_ECMDUNKNOWN ||
295                                     cmd != CMD_CAPABILITY)
296                                         printk(KERN_ERR "Error %d devcmd %d\n",
297                                                 err, _CMD_N(cmd));
298                                 return err;
299                         }
300
301                         if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
302                                 rmb();
303                                 *a0 = readq(&devcmd->args[0]);
304                                 *a1 = readq(&devcmd->args[1]);
305                         }
306
307                         return 0;
308                 }
309         }
310
311         printk(KERN_ERR "Timedout devcmd %d\n", _CMD_N(cmd));
312         return -ETIMEDOUT;
313 }
314
315 static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
316 {
317         u64 a0 = (u32)cmd, a1 = 0;
318         int wait = 1000;
319         int err;
320
321         err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
322
323         return !(err || a0);
324 }
325
326 int vnic_dev_fw_info(struct vnic_dev *vdev,
327         struct vnic_devcmd_fw_info **fw_info)
328 {
329         u64 a0, a1 = 0;
330         int wait = 1000;
331         int err = 0;
332
333         if (!vdev->fw_info) {
334                 vdev->fw_info = pci_alloc_consistent(vdev->pdev,
335                         sizeof(struct vnic_devcmd_fw_info),
336                         &vdev->fw_info_pa);
337                 if (!vdev->fw_info)
338                         return -ENOMEM;
339
340                 a0 = vdev->fw_info_pa;
341
342                 /* only get fw_info once and cache it */
343                 err = vnic_dev_cmd(vdev, CMD_MCPU_FW_INFO, &a0, &a1, wait);
344         }
345
346         *fw_info = vdev->fw_info;
347
348         return err;
349 }
350
351 int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver)
352 {
353         struct vnic_devcmd_fw_info *fw_info;
354         int err;
355
356         err = vnic_dev_fw_info(vdev, &fw_info);
357         if (err)
358                 return err;
359
360         if (strncmp(fw_info->hw_version, "A1", sizeof("A1")) == 0)
361                 *hw_ver = VNIC_DEV_HW_VER_A1;
362         else if (strncmp(fw_info->hw_version, "A2", sizeof("A2")) == 0)
363                 *hw_ver = VNIC_DEV_HW_VER_A2;
364         else
365                 *hw_ver = VNIC_DEV_HW_VER_UNKNOWN;
366
367         return 0;
368 }
369
370 int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
371         void *value)
372 {
373         u64 a0, a1;
374         int wait = 1000;
375         int err;
376
377         a0 = offset;
378         a1 = size;
379
380         err = vnic_dev_cmd(vdev, CMD_DEV_SPEC, &a0, &a1, wait);
381
382         switch (size) {
383         case 1: *(u8 *)value = (u8)a0; break;
384         case 2: *(u16 *)value = (u16)a0; break;
385         case 4: *(u32 *)value = (u32)a0; break;
386         case 8: *(u64 *)value = a0; break;
387         default: BUG(); break;
388         }
389
390         return err;
391 }
392
393 int vnic_dev_stats_clear(struct vnic_dev *vdev)
394 {
395         u64 a0 = 0, a1 = 0;
396         int wait = 1000;
397         return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait);
398 }
399
400 int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)
401 {
402         u64 a0, a1;
403         int wait = 1000;
404
405         if (!vdev->stats) {
406                 vdev->stats = pci_alloc_consistent(vdev->pdev,
407                         sizeof(struct vnic_stats), &vdev->stats_pa);
408                 if (!vdev->stats)
409                         return -ENOMEM;
410         }
411
412         *stats = vdev->stats;
413         a0 = vdev->stats_pa;
414         a1 = sizeof(struct vnic_stats);
415
416         return vnic_dev_cmd(vdev, CMD_STATS_DUMP, &a0, &a1, wait);
417 }
418
419 int vnic_dev_close(struct vnic_dev *vdev)
420 {
421         u64 a0 = 0, a1 = 0;
422         int wait = 1000;
423         return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait);
424 }
425
426 int vnic_dev_enable(struct vnic_dev *vdev)
427 {
428         u64 a0 = 0, a1 = 0;
429         int wait = 1000;
430         return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);
431 }
432
433 int vnic_dev_disable(struct vnic_dev *vdev)
434 {
435         u64 a0 = 0, a1 = 0;
436         int wait = 1000;
437         return vnic_dev_cmd(vdev, CMD_DISABLE, &a0, &a1, wait);
438 }
439
440 int vnic_dev_open(struct vnic_dev *vdev, int arg)
441 {
442         u64 a0 = (u32)arg, a1 = 0;
443         int wait = 1000;
444         return vnic_dev_cmd(vdev, CMD_OPEN, &a0, &a1, wait);
445 }
446
447 int vnic_dev_open_done(struct vnic_dev *vdev, int *done)
448 {
449         u64 a0 = 0, a1 = 0;
450         int wait = 1000;
451         int err;
452
453         *done = 0;
454
455         err = vnic_dev_cmd(vdev, CMD_OPEN_STATUS, &a0, &a1, wait);
456         if (err)
457                 return err;
458
459         *done = (a0 == 0);
460
461         return 0;
462 }
463
464 int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
465 {
466         u64 a0 = (u32)arg, a1 = 0;
467         int wait = 1000;
468         return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait);
469 }
470
471 int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
472 {
473         u64 a0 = 0, a1 = 0;
474         int wait = 1000;
475         int err;
476
477         *done = 0;
478
479         err = vnic_dev_cmd(vdev, CMD_SOFT_RESET_STATUS, &a0, &a1, wait);
480         if (err)
481                 return err;
482
483         *done = (a0 == 0);
484
485         return 0;
486 }
487
488 int vnic_dev_hang_notify(struct vnic_dev *vdev)
489 {
490         u64 a0, a1;
491         int wait = 1000;
492         return vnic_dev_cmd(vdev, CMD_HANG_NOTIFY, &a0, &a1, wait);
493 }
494
495 int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
496 {
497         u64 a0, a1;
498         int wait = 1000;
499         int err, i;
500
501         for (i = 0; i < ETH_ALEN; i++)
502                 mac_addr[i] = 0;
503
504         err = vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
505         if (err)
506                 return err;
507
508         for (i = 0; i < ETH_ALEN; i++)
509                 mac_addr[i] = ((u8 *)&a0)[i];
510
511         return 0;
512 }
513
514 void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
515         int broadcast, int promisc, int allmulti)
516 {
517         u64 a0, a1 = 0;
518         int wait = 1000;
519         int err;
520
521         a0 = (directed ? CMD_PFILTER_DIRECTED : 0) |
522              (multicast ? CMD_PFILTER_MULTICAST : 0) |
523              (broadcast ? CMD_PFILTER_BROADCAST : 0) |
524              (promisc ? CMD_PFILTER_PROMISCUOUS : 0) |
525              (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0);
526
527         err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait);
528         if (err)
529                 printk(KERN_ERR "Can't set packet filter\n");
530 }
531
532 void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
533 {
534         u64 a0 = 0, a1 = 0;
535         int wait = 1000;
536         int err;
537         int i;
538
539         for (i = 0; i < ETH_ALEN; i++)
540                 ((u8 *)&a0)[i] = addr[i];
541
542         err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
543         if (err)
544                 printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err);
545 }
546
547 void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
548 {
549         u64 a0 = 0, a1 = 0;
550         int wait = 1000;
551         int err;
552         int i;
553
554         for (i = 0; i < ETH_ALEN; i++)
555                 ((u8 *)&a0)[i] = addr[i];
556
557         err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
558         if (err)
559                 printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
560 }
561
562 int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
563 {
564         u64 a0 = intr, a1 = 0;
565         int wait = 1000;
566         int err;
567
568         err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait);
569         if (err)
570                 printk(KERN_ERR "Failed to raise INTR[%d], err %d\n",
571                         intr, err);
572
573         return err;
574 }
575
576 int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
577 {
578         u64 a0, a1;
579         int wait = 1000;
580         int r;
581
582         if (!vdev->notify) {
583                 vdev->notify = pci_alloc_consistent(vdev->pdev,
584                         sizeof(struct vnic_devcmd_notify),
585                         &vdev->notify_pa);
586                 if (!vdev->notify)
587                         return -ENOMEM;
588                 memset(vdev->notify, 0, sizeof(struct vnic_devcmd_notify));
589         }
590
591         a0 = vdev->notify_pa;
592         a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL;
593         a1 += sizeof(struct vnic_devcmd_notify);
594
595         r = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
596         vdev->notify_sz = (r == 0) ? (u32)a1 : 0;
597         return r;
598 }
599
600 void vnic_dev_notify_unset(struct vnic_dev *vdev)
601 {
602         u64 a0, a1;
603         int wait = 1000;
604
605         a0 = 0;  /* paddr = 0 to unset notify buffer */
606         a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */
607         a1 += sizeof(struct vnic_devcmd_notify);
608
609         vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
610         vdev->notify_sz = 0;
611 }
612
613 static int vnic_dev_notify_ready(struct vnic_dev *vdev)
614 {
615         u32 *words;
616         unsigned int nwords = vdev->notify_sz / 4;
617         unsigned int i;
618         u32 csum;
619
620         if (!vdev->notify || !vdev->notify_sz)
621                 return 0;
622
623         do {
624                 csum = 0;
625                 memcpy(&vdev->notify_copy, vdev->notify, vdev->notify_sz);
626                 words = (u32 *)&vdev->notify_copy;
627                 for (i = 1; i < nwords; i++)
628                         csum += words[i];
629         } while (csum != words[0]);
630
631         return 1;
632 }
633
634 int vnic_dev_init(struct vnic_dev *vdev, int arg)
635 {
636         u64 a0 = (u32)arg, a1 = 0;
637         int wait = 1000;
638         int r = 0;
639
640         if (vdev->cap_flags & VNIC_DEV_CAP_INIT)
641                 r = vnic_dev_cmd(vdev, CMD_INIT, &a0, &a1, wait);
642         else {
643                 vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
644                 if (a0 & CMD_INITF_DEFAULT_MAC) {
645                         // Emulate these for old CMD_INIT_v1 which
646                         // didn't pass a0 so no CMD_INITF_*.
647                         vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
648                         vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
649                 }
650         }
651         return r;
652 }
653
654 int vnic_dev_link_status(struct vnic_dev *vdev)
655 {
656         if (vdev->linkstatus)
657                 return *vdev->linkstatus;
658
659         if (!vnic_dev_notify_ready(vdev))
660                 return 0;
661
662         return vdev->notify_copy.link_state;
663 }
664
665 u32 vnic_dev_port_speed(struct vnic_dev *vdev)
666 {
667         if (!vnic_dev_notify_ready(vdev))
668                 return 0;
669
670         return vdev->notify_copy.port_speed;
671 }
672
673 u32 vnic_dev_msg_lvl(struct vnic_dev *vdev)
674 {
675         if (!vnic_dev_notify_ready(vdev))
676                 return 0;
677
678         return vdev->notify_copy.msglvl;
679 }
680
681 u32 vnic_dev_mtu(struct vnic_dev *vdev)
682 {
683         if (!vnic_dev_notify_ready(vdev))
684                 return 0;
685
686         return vdev->notify_copy.mtu;
687 }
688
689 u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev)
690 {
691         if (!vnic_dev_notify_ready(vdev))
692                 return 0;
693
694         return vdev->notify_copy.link_down_cnt;
695 }
696
697 u32 vnic_dev_notify_status(struct vnic_dev *vdev)
698 {
699         if (!vnic_dev_notify_ready(vdev))
700                 return 0;
701
702         return vdev->notify_copy.status;
703 }
704
705 void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
706         enum vnic_dev_intr_mode intr_mode)
707 {
708         vdev->intr_mode = intr_mode;
709 }
710
711 enum vnic_dev_intr_mode vnic_dev_get_intr_mode(
712         struct vnic_dev *vdev)
713 {
714         return vdev->intr_mode;
715 }
716
717 void vnic_dev_unregister(struct vnic_dev *vdev)
718 {
719         if (vdev) {
720                 if (vdev->notify)
721                         pci_free_consistent(vdev->pdev,
722                                 sizeof(struct vnic_devcmd_notify),
723                                 vdev->notify,
724                                 vdev->notify_pa);
725                 if (vdev->linkstatus)
726                         pci_free_consistent(vdev->pdev,
727                                 sizeof(u32),
728                                 vdev->linkstatus,
729                                 vdev->linkstatus_pa);
730                 if (vdev->stats)
731                         pci_free_consistent(vdev->pdev,
732                                 sizeof(struct vnic_dev),
733                                 vdev->stats, vdev->stats_pa);
734                 if (vdev->fw_info)
735                         pci_free_consistent(vdev->pdev,
736                                 sizeof(struct vnic_devcmd_fw_info),
737                                 vdev->fw_info, vdev->fw_info_pa);
738                 kfree(vdev);
739         }
740 }
741
742 struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
743         void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
744         unsigned int num_bars)
745 {
746         if (!vdev) {
747                 vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC);
748                 if (!vdev)
749                         return NULL;
750         }
751
752         vdev->priv = priv;
753         vdev->pdev = pdev;
754
755         if (vnic_dev_discover_res(vdev, bar, num_bars))
756                 goto err_out;
757
758         vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0);
759         if (!vdev->devcmd)
760                 goto err_out;
761
762         vdev->cap_flags = 0;
763
764         if (vnic_dev_capable(vdev, CMD_INIT))
765                 vdev->cap_flags |= VNIC_DEV_CAP_INIT;
766
767         return vdev;
768
769 err_out:
770         vnic_dev_unregister(vdev);
771         return NULL;
772 }
773
774