2 * Copyright 2008 Cisco Systems, Inc. All rights reserved.
3 * Copyright 2007 Nuova Systems, Inc. All rights reserved.
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.
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
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/types.h>
22 #include <linux/pci.h>
23 #include <linux/delay.h>
24 #include <linux/if_ether.h>
25 #include <linux/slab.h>
26 #include "vnic_resource.h"
27 #include "vnic_devcmd.h"
29 #include "vnic_stats.h"
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
;
46 dma_addr_t linkstatus_pa
;
47 struct vnic_stats
*stats
;
49 struct vnic_devcmd_fw_info
*fw_info
;
50 dma_addr_t fw_info_pa
;
53 #define VNIC_MAX_RES_HDR_SIZE \
54 (sizeof(struct vnic_resource_header) + \
55 sizeof(struct vnic_resource) * RES_TYPE_MAX)
56 #define VNIC_RES_STRIDE 128
58 void *vnic_dev_priv(struct vnic_dev
*vdev
)
63 static int vnic_dev_discover_res(struct vnic_dev
*vdev
,
64 struct vnic_dev_bar
*bar
)
66 struct vnic_resource_header __iomem
*rh
;
67 struct vnic_resource __iomem
*r
;
70 if (bar
->len
< VNIC_MAX_RES_HDR_SIZE
) {
71 printk(KERN_ERR
"vNIC BAR0 res hdr length error\n");
77 printk(KERN_ERR
"vNIC BAR0 res hdr not mem-mapped\n");
81 if (ioread32(&rh
->magic
) != VNIC_RES_MAGIC
||
82 ioread32(&rh
->version
) != VNIC_RES_VERSION
) {
83 printk(KERN_ERR
"vNIC BAR0 res magic/version error "
84 "exp (%lx/%lx) curr (%x/%x)\n",
85 VNIC_RES_MAGIC
, VNIC_RES_VERSION
,
86 ioread32(&rh
->magic
), ioread32(&rh
->version
));
90 r
= (struct vnic_resource __iomem
*)(rh
+ 1);
92 while ((type
= ioread8(&r
->type
)) != RES_TYPE_EOL
) {
94 u8 bar_num
= ioread8(&r
->bar
);
95 u32 bar_offset
= ioread32(&r
->bar_offset
);
96 u32 count
= ioread32(&r
->count
);
101 if (bar_num
!= 0) /* only mapping in BAR0 resources */
108 case RES_TYPE_INTR_CTRL
:
109 /* each count is stride bytes long */
110 len
= count
* VNIC_RES_STRIDE
;
111 if (len
+ bar_offset
> bar
->len
) {
112 printk(KERN_ERR
"vNIC BAR0 resource %d "
113 "out-of-bounds, offset 0x%x + "
114 "size 0x%x > bar len 0x%lx\n",
121 case RES_TYPE_INTR_PBA_LEGACY
:
122 case RES_TYPE_DEVCMD
:
129 vdev
->res
[type
].count
= count
;
130 vdev
->res
[type
].vaddr
= (char __iomem
*)bar
->vaddr
+ bar_offset
;
136 unsigned int vnic_dev_get_res_count(struct vnic_dev
*vdev
,
137 enum vnic_res_type type
)
139 return vdev
->res
[type
].count
;
142 void __iomem
*vnic_dev_get_res(struct vnic_dev
*vdev
, enum vnic_res_type type
,
145 if (!vdev
->res
[type
].vaddr
)
152 case RES_TYPE_INTR_CTRL
:
153 return (char __iomem
*)vdev
->res
[type
].vaddr
+
154 index
* VNIC_RES_STRIDE
;
156 return (char __iomem
*)vdev
->res
[type
].vaddr
;
160 unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring
*ring
,
161 unsigned int desc_count
,
162 unsigned int desc_size
)
164 /* The base address of the desc rings must be 512 byte aligned.
165 * Descriptor count is aligned to groups of 32 descriptors. A
166 * count of 0 means the maximum 4096 descriptors. Descriptor
167 * size is aligned to 16 bytes.
170 unsigned int count_align
= 32;
171 unsigned int desc_align
= 16;
173 ring
->base_align
= 512;
178 ring
->desc_count
= ALIGN(desc_count
, count_align
);
180 ring
->desc_size
= ALIGN(desc_size
, desc_align
);
182 ring
->size
= ring
->desc_count
* ring
->desc_size
;
183 ring
->size_unaligned
= ring
->size
+ ring
->base_align
;
185 return ring
->size_unaligned
;
188 void vnic_dev_clear_desc_ring(struct vnic_dev_ring
*ring
)
190 memset(ring
->descs
, 0, ring
->size
);
193 int vnic_dev_alloc_desc_ring(struct vnic_dev
*vdev
, struct vnic_dev_ring
*ring
,
194 unsigned int desc_count
, unsigned int desc_size
)
196 vnic_dev_desc_ring_size(ring
, desc_count
, desc_size
);
198 ring
->descs_unaligned
= pci_alloc_consistent(vdev
->pdev
,
199 ring
->size_unaligned
,
200 &ring
->base_addr_unaligned
);
202 if (!ring
->descs_unaligned
) {
204 "Failed to allocate ring (size=%d), aborting\n",
209 ring
->base_addr
= ALIGN(ring
->base_addr_unaligned
,
211 ring
->descs
= (u8
*)ring
->descs_unaligned
+
212 (ring
->base_addr
- ring
->base_addr_unaligned
);
214 vnic_dev_clear_desc_ring(ring
);
216 ring
->desc_avail
= ring
->desc_count
- 1;
221 void vnic_dev_free_desc_ring(struct vnic_dev
*vdev
, struct vnic_dev_ring
*ring
)
224 pci_free_consistent(vdev
->pdev
,
225 ring
->size_unaligned
,
226 ring
->descs_unaligned
,
227 ring
->base_addr_unaligned
);
232 int vnic_dev_cmd(struct vnic_dev
*vdev
, enum vnic_devcmd_cmd cmd
,
233 u64
*a0
, u64
*a1
, int wait
)
235 struct vnic_devcmd __iomem
*devcmd
= vdev
->devcmd
;
238 int dev_cmd_err
[] = {
239 /* convert from fw's version of error.h to host's version */
241 EINVAL
, /* ERR_EINVAL */
242 EFAULT
, /* ERR_EFAULT */
243 EPERM
, /* ERR_EPERM */
244 EBUSY
, /* ERR_EBUSY */
248 status
= ioread32(&devcmd
->status
);
249 if (status
& STAT_BUSY
) {
250 printk(KERN_ERR
"Busy devcmd %d\n", _CMD_N(cmd
));
254 if (_CMD_DIR(cmd
) & _CMD_DIR_WRITE
) {
255 writeq(*a0
, &devcmd
->args
[0]);
256 writeq(*a1
, &devcmd
->args
[1]);
260 iowrite32(cmd
, &devcmd
->cmd
);
262 if ((_CMD_FLAGS(cmd
) & _CMD_FLAGS_NOWAIT
))
265 for (delay
= 0; delay
< wait
; delay
++) {
269 status
= ioread32(&devcmd
->status
);
270 if (!(status
& STAT_BUSY
)) {
272 if (status
& STAT_ERROR
) {
273 err
= dev_cmd_err
[(int)readq(&devcmd
->args
[0])];
274 printk(KERN_ERR
"Error %d devcmd %d\n",
279 if (_CMD_DIR(cmd
) & _CMD_DIR_READ
) {
281 *a0
= readq(&devcmd
->args
[0]);
282 *a1
= readq(&devcmd
->args
[1]);
289 printk(KERN_ERR
"Timedout devcmd %d\n", _CMD_N(cmd
));
293 int vnic_dev_fw_info(struct vnic_dev
*vdev
,
294 struct vnic_devcmd_fw_info
**fw_info
)
300 if (!vdev
->fw_info
) {
301 vdev
->fw_info
= pci_alloc_consistent(vdev
->pdev
,
302 sizeof(struct vnic_devcmd_fw_info
),
307 a0
= vdev
->fw_info_pa
;
309 /* only get fw_info once and cache it */
310 err
= vnic_dev_cmd(vdev
, CMD_MCPU_FW_INFO
, &a0
, &a1
, wait
);
313 *fw_info
= vdev
->fw_info
;
318 int vnic_dev_spec(struct vnic_dev
*vdev
, unsigned int offset
, unsigned int size
,
328 err
= vnic_dev_cmd(vdev
, CMD_DEV_SPEC
, &a0
, &a1
, wait
);
332 *(u8
*)value
= (u8
)a0
;
335 *(u16
*)value
= (u16
)a0
;
338 *(u32
*)value
= (u32
)a0
;
351 int vnic_dev_stats_clear(struct vnic_dev
*vdev
)
355 return vnic_dev_cmd(vdev
, CMD_STATS_CLEAR
, &a0
, &a1
, wait
);
358 int vnic_dev_stats_dump(struct vnic_dev
*vdev
, struct vnic_stats
**stats
)
364 vdev
->stats
= pci_alloc_consistent(vdev
->pdev
,
365 sizeof(struct vnic_stats
), &vdev
->stats_pa
);
370 *stats
= vdev
->stats
;
372 a1
= sizeof(struct vnic_stats
);
374 return vnic_dev_cmd(vdev
, CMD_STATS_DUMP
, &a0
, &a1
, wait
);
377 int vnic_dev_close(struct vnic_dev
*vdev
)
381 return vnic_dev_cmd(vdev
, CMD_CLOSE
, &a0
, &a1
, wait
);
384 int vnic_dev_enable(struct vnic_dev
*vdev
)
388 return vnic_dev_cmd(vdev
, CMD_ENABLE
, &a0
, &a1
, wait
);
391 int vnic_dev_disable(struct vnic_dev
*vdev
)
395 return vnic_dev_cmd(vdev
, CMD_DISABLE
, &a0
, &a1
, wait
);
398 int vnic_dev_open(struct vnic_dev
*vdev
, int arg
)
400 u64 a0
= (u32
)arg
, a1
= 0;
402 return vnic_dev_cmd(vdev
, CMD_OPEN
, &a0
, &a1
, wait
);
405 int vnic_dev_open_done(struct vnic_dev
*vdev
, int *done
)
413 err
= vnic_dev_cmd(vdev
, CMD_OPEN_STATUS
, &a0
, &a1
, wait
);
422 int vnic_dev_soft_reset(struct vnic_dev
*vdev
, int arg
)
424 u64 a0
= (u32
)arg
, a1
= 0;
426 return vnic_dev_cmd(vdev
, CMD_SOFT_RESET
, &a0
, &a1
, wait
);
429 int vnic_dev_soft_reset_done(struct vnic_dev
*vdev
, int *done
)
437 err
= vnic_dev_cmd(vdev
, CMD_SOFT_RESET_STATUS
, &a0
, &a1
, wait
);
446 int vnic_dev_hang_notify(struct vnic_dev
*vdev
)
450 return vnic_dev_cmd(vdev
, CMD_HANG_NOTIFY
, &a0
, &a1
, wait
);
453 int vnic_dev_mac_addr(struct vnic_dev
*vdev
, u8
*mac_addr
)
459 for (i
= 0; i
< ETH_ALEN
; i
++)
462 err
= vnic_dev_cmd(vdev
, CMD_MAC_ADDR
, &a0
, &a1
, wait
);
466 for (i
= 0; i
< ETH_ALEN
; i
++)
467 mac_addr
[i
] = ((u8
*)&a0
)[i
];
472 void vnic_dev_packet_filter(struct vnic_dev
*vdev
, int directed
, int multicast
,
473 int broadcast
, int promisc
, int allmulti
)
479 a0
= (directed
? CMD_PFILTER_DIRECTED
: 0) |
480 (multicast
? CMD_PFILTER_MULTICAST
: 0) |
481 (broadcast
? CMD_PFILTER_BROADCAST
: 0) |
482 (promisc
? CMD_PFILTER_PROMISCUOUS
: 0) |
483 (allmulti
? CMD_PFILTER_ALL_MULTICAST
: 0);
485 err
= vnic_dev_cmd(vdev
, CMD_PACKET_FILTER
, &a0
, &a1
, wait
);
487 printk(KERN_ERR
"Can't set packet filter\n");
490 void vnic_dev_add_addr(struct vnic_dev
*vdev
, u8
*addr
)
497 for (i
= 0; i
< ETH_ALEN
; i
++)
498 ((u8
*)&a0
)[i
] = addr
[i
];
500 err
= vnic_dev_cmd(vdev
, CMD_ADDR_ADD
, &a0
, &a1
, wait
);
503 "Can't add addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
504 addr
[0], addr
[1], addr
[2], addr
[3], addr
[4], addr
[5],
508 void vnic_dev_del_addr(struct vnic_dev
*vdev
, u8
*addr
)
515 for (i
= 0; i
< ETH_ALEN
; i
++)
516 ((u8
*)&a0
)[i
] = addr
[i
];
518 err
= vnic_dev_cmd(vdev
, CMD_ADDR_DEL
, &a0
, &a1
, wait
);
521 "Can't del addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n",
522 addr
[0], addr
[1], addr
[2], addr
[3], addr
[4], addr
[5],
526 int vnic_dev_notify_set(struct vnic_dev
*vdev
, u16 intr
)
532 vdev
->notify
= pci_alloc_consistent(vdev
->pdev
,
533 sizeof(struct vnic_devcmd_notify
),
539 a0
= vdev
->notify_pa
;
540 a1
= ((u64
)intr
<< 32) & 0x0000ffff00000000ULL
;
541 a1
+= sizeof(struct vnic_devcmd_notify
);
543 return vnic_dev_cmd(vdev
, CMD_NOTIFY
, &a0
, &a1
, wait
);
546 void vnic_dev_notify_unset(struct vnic_dev
*vdev
)
551 a0
= 0; /* paddr = 0 to unset notify buffer */
552 a1
= 0x0000ffff00000000ULL
; /* intr num = -1 to unreg for intr */
553 a1
+= sizeof(struct vnic_devcmd_notify
);
555 vnic_dev_cmd(vdev
, CMD_NOTIFY
, &a0
, &a1
, wait
);
558 static int vnic_dev_notify_ready(struct vnic_dev
*vdev
)
561 unsigned int nwords
= sizeof(struct vnic_devcmd_notify
) / 4;
570 memcpy(&vdev
->notify_copy
, vdev
->notify
,
571 sizeof(struct vnic_devcmd_notify
));
572 words
= (u32
*)&vdev
->notify_copy
;
573 for (i
= 1; i
< nwords
; i
++)
575 } while (csum
!= words
[0]);
580 int vnic_dev_init(struct vnic_dev
*vdev
, int arg
)
582 u64 a0
= (u32
)arg
, a1
= 0;
584 return vnic_dev_cmd(vdev
, CMD_INIT
, &a0
, &a1
, wait
);
587 int vnic_dev_link_status(struct vnic_dev
*vdev
)
589 if (vdev
->linkstatus
)
590 return *vdev
->linkstatus
;
592 if (!vnic_dev_notify_ready(vdev
))
595 return vdev
->notify_copy
.link_state
;
598 u32
vnic_dev_port_speed(struct vnic_dev
*vdev
)
600 if (!vnic_dev_notify_ready(vdev
))
603 return vdev
->notify_copy
.port_speed
;
606 u32
vnic_dev_msg_lvl(struct vnic_dev
*vdev
)
608 if (!vnic_dev_notify_ready(vdev
))
611 return vdev
->notify_copy
.msglvl
;
614 u32
vnic_dev_mtu(struct vnic_dev
*vdev
)
616 if (!vnic_dev_notify_ready(vdev
))
619 return vdev
->notify_copy
.mtu
;
622 u32
vnic_dev_link_down_cnt(struct vnic_dev
*vdev
)
624 if (!vnic_dev_notify_ready(vdev
))
627 return vdev
->notify_copy
.link_down_cnt
;
630 void vnic_dev_set_intr_mode(struct vnic_dev
*vdev
,
631 enum vnic_dev_intr_mode intr_mode
)
633 vdev
->intr_mode
= intr_mode
;
636 enum vnic_dev_intr_mode
vnic_dev_get_intr_mode(
637 struct vnic_dev
*vdev
)
639 return vdev
->intr_mode
;
642 void vnic_dev_unregister(struct vnic_dev
*vdev
)
646 pci_free_consistent(vdev
->pdev
,
647 sizeof(struct vnic_devcmd_notify
),
650 if (vdev
->linkstatus
)
651 pci_free_consistent(vdev
->pdev
,
654 vdev
->linkstatus_pa
);
656 pci_free_consistent(vdev
->pdev
,
657 sizeof(struct vnic_stats
),
658 vdev
->stats
, vdev
->stats_pa
);
660 pci_free_consistent(vdev
->pdev
,
661 sizeof(struct vnic_devcmd_fw_info
),
662 vdev
->fw_info
, vdev
->fw_info_pa
);
667 struct vnic_dev
*vnic_dev_register(struct vnic_dev
*vdev
,
668 void *priv
, struct pci_dev
*pdev
, struct vnic_dev_bar
*bar
)
671 vdev
= kzalloc(sizeof(struct vnic_dev
), GFP_KERNEL
);
679 if (vnic_dev_discover_res(vdev
, bar
))
682 vdev
->devcmd
= vnic_dev_get_res(vdev
, RES_TYPE_DEVCMD
, 0);
689 vnic_dev_unregister(vdev
);