diff options
author | Scott Feldman <scofeldm@cisco.com> | 2010-05-17 22:50:19 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-17 22:50:19 -0700 |
commit | f8bd909183acffad68780b10c1cdf36161cfd5d1 (patch) | |
tree | aefec6e6f1e67e93bc1b2ec223f974a4cd34f00f /drivers/net/enic/vnic_dev.c | |
parent | 57b610805ce92dbd79fc97509f80fa5391b99623 (diff) |
net: Add ndo_{set|get}_vf_port support for enic dynamic vnics
Add enic ndo_{set|get}_vf_port ops to support setting/getting
port-profile for enic dynamic devices. Enic dynamic devices are just like
normal enic eth devices except dynamic enics require an extra configuration
step to assign a port-profile identifier to the interface before the
interface is useable. Once a port-profile is assigned, link comes up on the
interface and is ready for I/O. The port-profile is used to configure the
network port assigned to the interface. The network port configuration
includes VLAN membership, QoS policies, and port security settings typical
of a data center network.
A dynamic enic initially has a zero-mac address. Before a port-profile is
assigned, a valid non-zero unicast mac address should be assign to the
dynamic enic interface.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r-- | drivers/net/enic/vnic_dev.c | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index d43a9d43bbff..2b3e16db5c82 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -530,7 +530,7 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, printk(KERN_ERR "Can't set packet filter\n"); } -void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) +int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) { u64 a0 = 0, a1 = 0; int wait = 1000; @@ -543,9 +543,11 @@ void vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait); if (err) printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err); + + return err; } -void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) +int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) { u64 a0 = 0, a1 = 0; int wait = 1000; @@ -558,6 +560,8 @@ void vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr) err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait); if (err) printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err); + + return err; } int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) @@ -682,6 +686,56 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg) return r; } +int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err) +{ + u64 a0 = 0, a1 = 0; + int wait = 1000; + int ret; + + *done = 0; + + ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait); + if (ret) + return ret; + + *done = (a0 == 0); + + *err = (a0 == 0) ? a1 : 0; + + return 0; +} + +int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len) +{ + u64 a0, a1 = len; + int wait = 1000; + u64 prov_pa; + void *prov_buf; + int ret; + + prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa); + if (!prov_buf) + return -ENOMEM; + + memcpy(prov_buf, buf, len); + + a0 = prov_pa; + + ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait); + + pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa); + + return ret; +} + +int vnic_dev_deinit(struct vnic_dev *vdev) +{ + u64 a0 = 0, a1 = 0; + int wait = 1000; + + return vnic_dev_cmd(vdev, CMD_DEINIT, &a0, &a1, wait); +} + int vnic_dev_link_status(struct vnic_dev *vdev) { if (vdev->linkstatus) |