aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/enic/vnic_dev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 10:37:28 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-14 10:37:28 -0700
commitd7e9660ad9d5e0845f52848bce31bcf5cdcdea6b (patch)
treec6c67d145771187b194d79d603742b31090a59d6 /drivers/net/enic/vnic_dev.c
parentb8cb48aae1b8c50b37dcb7710363aa69a7a0d9ca (diff)
parent13af7a6ea502fcdd4c0e3d7de6e332b102309491 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1623 commits) netxen: update copyright netxen: fix tx timeout recovery netxen: fix file firmware leak netxen: improve pci memory access netxen: change firmware write size tg3: Fix return ring size breakage netxen: build fix for INET=n cdc-phonet: autoconfigure Phonet address Phonet: back-end for autoconfigured addresses Phonet: fix netlink address dump error handling ipv6: Add IFA_F_DADFAILED flag net: Add DEVTYPE support for Ethernet based devices mv643xx_eth.c: remove unused txq_set_wrr() ucc_geth: Fix hangs after switching from full to half duplex ucc_geth: Rearrange some code to avoid forward declarations phy/marvell: Make non-aneg speed/duplex forcing work for 88E1111 PHYs drivers/net/phy: introduce missing kfree drivers/net/wan: introduce missing kfree net: force bridge module(s) to be GPL Subject: [PATCH] appletalk: Fix skb leak when ipddp interface is not loaded ... Fixed up trivial conflicts: - arch/x86/include/asm/socket.h converted to <asm-generic/socket.h> in the x86 tree. The generic header has the same new #define's, so that works out fine. - drivers/net/tun.c fix conflict between 89f56d1e9 ("tun: reuse struct sock fields") that switched over to using 'tun->socket.sk' instead of the redundantly available (and thus removed) 'tun->sk', and 2b980dbd ("lsm: Add hooks to the TUN driver") which added a new 'tun->sk' use. Noted in 'next' by Stephen Rothwell.
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r--drivers/net/enic/vnic_dev.c74
1 files changed, 66 insertions, 8 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index e21b9d636ae..29a48e8b59d 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -31,6 +31,7 @@
struct vnic_res {
void __iomem *vaddr;
+ dma_addr_t bus_addr;
unsigned int count;
};
@@ -67,12 +68,15 @@ void *vnic_dev_priv(struct vnic_dev *vdev)
}
static int vnic_dev_discover_res(struct vnic_dev *vdev,
- struct vnic_dev_bar *bar)
+ struct vnic_dev_bar *bar, unsigned int num_bars)
{
struct vnic_resource_header __iomem *rh;
struct vnic_resource __iomem *r;
u8 type;
+ if (num_bars == 0)
+ return -EINVAL;
+
if (bar->len < VNIC_MAX_RES_HDR_SIZE) {
printk(KERN_ERR "vNIC BAR0 res hdr length error\n");
return -EINVAL;
@@ -104,7 +108,10 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
r++;
- if (bar_num != 0) /* only mapping in BAR0 resources */
+ if (bar_num >= num_bars)
+ continue;
+
+ if (!bar[bar_num].len || !bar[bar_num].vaddr)
continue;
switch (type) {
@@ -114,13 +121,13 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
case RES_TYPE_INTR_CTRL:
/* each count is stride bytes long */
len = count * VNIC_RES_STRIDE;
- if (len + bar_offset > bar->len) {
+ if (len + bar_offset > bar[bar_num].len) {
printk(KERN_ERR "vNIC BAR0 resource %d "
"out-of-bounds, offset 0x%x + "
"size 0x%x > bar len 0x%lx\n",
type, bar_offset,
len,
- bar->len);
+ bar[bar_num].len);
return -EINVAL;
}
break;
@@ -133,7 +140,9 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
}
vdev->res[type].count = count;
- vdev->res[type].vaddr = (char __iomem *)bar->vaddr + bar_offset;
+ vdev->res[type].vaddr = (char __iomem *)bar[bar_num].vaddr +
+ bar_offset;
+ vdev->res[type].bus_addr = bar[bar_num].bus_addr + bar_offset;
}
return 0;
@@ -163,6 +172,21 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
}
}
+dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev,
+ enum vnic_res_type type, unsigned int index)
+{
+ switch (type) {
+ case RES_TYPE_WQ:
+ case RES_TYPE_RQ:
+ case RES_TYPE_CQ:
+ case RES_TYPE_INTR_CTRL:
+ return vdev->res[type].bus_addr +
+ index * VNIC_RES_STRIDE;
+ default:
+ return vdev->res[type].bus_addr;
+ }
+}
+
unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
unsigned int desc_count, unsigned int desc_size)
{
@@ -257,7 +281,7 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
iowrite32(cmd, &devcmd->cmd);
if ((_CMD_FLAGS(cmd) & _CMD_FLAGS_NOWAIT))
- return 0;
+ return 0;
for (delay = 0; delay < wait; delay++) {
@@ -325,6 +349,25 @@ int vnic_dev_fw_info(struct vnic_dev *vdev,
return err;
}
+int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver)
+{
+ struct vnic_devcmd_fw_info *fw_info;
+ int err;
+
+ err = vnic_dev_fw_info(vdev, &fw_info);
+ if (err)
+ return err;
+
+ if (strncmp(fw_info->hw_version, "A1", sizeof("A1")) == 0)
+ *hw_ver = VNIC_DEV_HW_VER_A1;
+ else if (strncmp(fw_info->hw_version, "A2", sizeof("A2")) == 0)
+ *hw_ver = VNIC_DEV_HW_VER_A2;
+ else
+ *hw_ver = VNIC_DEV_HW_VER_UNKNOWN;
+
+ return 0;
+}
+
int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
void *value)
{
@@ -517,6 +560,20 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
}
+int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
+{
+ u64 a0 = intr, a1 = 0;
+ int wait = 1000;
+ int err;
+
+ err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait);
+ if (err)
+ printk(KERN_ERR "Failed to raise INTR[%d], err %d\n",
+ intr, err);
+
+ return err;
+}
+
int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
{
u64 a0, a1;
@@ -684,7 +741,8 @@ void vnic_dev_unregister(struct vnic_dev *vdev)
}
struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
- void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar)
+ void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
+ unsigned int num_bars)
{
if (!vdev) {
vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC);
@@ -695,7 +753,7 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
vdev->priv = priv;
vdev->pdev = pdev;
- if (vnic_dev_discover_res(vdev, bar))
+ if (vnic_dev_discover_res(vdev, bar, num_bars))
goto err_out;
vdev->devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0);