diff options
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r-- | drivers/net/enic/vnic_dev.c | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index e21b9d636aec..d5c28efedd98 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | struct vnic_res { | 32 | struct vnic_res { |
33 | void __iomem *vaddr; | 33 | void __iomem *vaddr; |
34 | dma_addr_t bus_addr; | ||
34 | unsigned int count; | 35 | unsigned int count; |
35 | }; | 36 | }; |
36 | 37 | ||
@@ -67,12 +68,15 @@ void *vnic_dev_priv(struct vnic_dev *vdev) | |||
67 | } | 68 | } |
68 | 69 | ||
69 | static int vnic_dev_discover_res(struct vnic_dev *vdev, | 70 | static int vnic_dev_discover_res(struct vnic_dev *vdev, |
70 | struct vnic_dev_bar *bar) | 71 | struct vnic_dev_bar *bar, unsigned int num_bars) |
71 | { | 72 | { |
72 | struct vnic_resource_header __iomem *rh; | 73 | struct vnic_resource_header __iomem *rh; |
73 | struct vnic_resource __iomem *r; | 74 | struct vnic_resource __iomem *r; |
74 | u8 type; | 75 | u8 type; |
75 | 76 | ||
77 | if (num_bars == 0) | ||
78 | return -EINVAL; | ||
79 | |||
76 | if (bar->len < VNIC_MAX_RES_HDR_SIZE) { | 80 | if (bar->len < VNIC_MAX_RES_HDR_SIZE) { |
77 | printk(KERN_ERR "vNIC BAR0 res hdr length error\n"); | 81 | printk(KERN_ERR "vNIC BAR0 res hdr length error\n"); |
78 | return -EINVAL; | 82 | return -EINVAL; |
@@ -104,7 +108,10 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, | |||
104 | 108 | ||
105 | r++; | 109 | r++; |
106 | 110 | ||
107 | if (bar_num != 0) /* only mapping in BAR0 resources */ | 111 | if (bar_num >= num_bars) |
112 | continue; | ||
113 | |||
114 | if (!bar[bar_num].len || !bar[bar_num].vaddr) | ||
108 | continue; | 115 | continue; |
109 | 116 | ||
110 | switch (type) { | 117 | switch (type) { |
@@ -114,13 +121,13 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, | |||
114 | case RES_TYPE_INTR_CTRL: | 121 | case RES_TYPE_INTR_CTRL: |
115 | /* each count is stride bytes long */ | 122 | /* each count is stride bytes long */ |
116 | len = count * VNIC_RES_STRIDE; | 123 | len = count * VNIC_RES_STRIDE; |
117 | if (len + bar_offset > bar->len) { | 124 | if (len + bar_offset > bar[bar_num].len) { |
118 | printk(KERN_ERR "vNIC BAR0 resource %d " | 125 | printk(KERN_ERR "vNIC BAR0 resource %d " |
119 | "out-of-bounds, offset 0x%x + " | 126 | "out-of-bounds, offset 0x%x + " |
120 | "size 0x%x > bar len 0x%lx\n", | 127 | "size 0x%x > bar len 0x%lx\n", |
121 | type, bar_offset, | 128 | type, bar_offset, |
122 | len, | 129 | len, |
123 | bar->len); | 130 | bar[bar_num].len); |
124 | return -EINVAL; | 131 | return -EINVAL; |
125 | } | 132 | } |
126 | break; | 133 | break; |
@@ -133,7 +140,9 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, | |||
133 | } | 140 | } |
134 | 141 | ||
135 | vdev->res[type].count = count; | 142 | vdev->res[type].count = count; |
136 | vdev->res[type].vaddr = (char __iomem *)bar->vaddr + bar_offset; | 143 | vdev->res[type].vaddr = (char __iomem *)bar[bar_num].vaddr + |
144 | bar_offset; | ||
145 | vdev->res[type].bus_addr = bar[bar_num].bus_addr + bar_offset; | ||
137 | } | 146 | } |
138 | 147 | ||
139 | return 0; | 148 | return 0; |
@@ -163,6 +172,21 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, | |||
163 | } | 172 | } |
164 | } | 173 | } |
165 | 174 | ||
175 | dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev, | ||
176 | enum vnic_res_type type, unsigned int index) | ||
177 | { | ||
178 | switch (type) { | ||
179 | case RES_TYPE_WQ: | ||
180 | case RES_TYPE_RQ: | ||
181 | case RES_TYPE_CQ: | ||
182 | case RES_TYPE_INTR_CTRL: | ||
183 | return vdev->res[type].bus_addr + | ||
184 | index * VNIC_RES_STRIDE; | ||
185 | default: | ||
186 | return vdev->res[type].bus_addr; | ||
187 | } | ||
188 | } | ||
189 | |||
166 | unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, | 190 | unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, |
167 | unsigned int desc_count, unsigned int desc_size) | 191 | unsigned int desc_count, unsigned int desc_size) |
168 | { | 192 | { |
@@ -257,7 +281,7 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, | |||
257 | iowrite32(cmd, &devcmd->cmd); | 281 | iowrite32(cmd, &devcmd->cmd); |
258 | 282 | ||
259 | if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT)) | 283 | if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT)) |
260 | return 0; | 284 | return 0; |
261 | 285 | ||
262 | for (delay = 0; delay < wait; delay++) { | 286 | for (delay = 0; delay < wait; delay++) { |
263 | 287 | ||
@@ -684,7 +708,8 @@ void vnic_dev_unregister(struct vnic_dev *vdev) | |||
684 | } | 708 | } |
685 | 709 | ||
686 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | 710 | struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, |
687 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar) | 711 | void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar, |
712 | unsigned int num_bars) | ||
688 | { | 713 | { |
689 | if (!vdev) { | 714 | if (!vdev) { |
690 | vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC); | 715 | vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC); |
@@ -695,7 +720,7 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, | |||
695 | vdev->priv = priv; | 720 | vdev->priv = priv; |
696 | vdev->pdev = pdev; | 721 | vdev->pdev = pdev; |
697 | 722 | ||
698 | if (vnic_dev_discover_res(vdev, bar)) | 723 | if (vnic_dev_discover_res(vdev, bar, num_bars)) |
699 | goto err_out; | 724 | goto err_out; |
700 | 725 | ||
701 | vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0); | 726 | vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0); |