This patch add support RDMAoE for mlx4. Since mlx4_ib now needs to reference
mlx4_en netdevices, a new mechanism was added. Two new fields were added to
struct mlx4_interface to define a protocol and a get_prot_dev method to
retrieve the corresponding protocol's net device.  An implementation of the new
verb ib_get_port_link_type() - mlx4_ib_get_port_link_type - was added.
mlx4_ib_query_port() has been modified to support eth link types. An interface
is considered to be active if its corresponding eth interface is active. Code
for setting the GID table of a port has been added. Currently, each IB port has
a single GID entry in its table and that GID entery equals the link local IPv6
address.

Signed-off-by: Eli Cohen <e...@mellanox.co.il>
---
 drivers/infiniband/hw/mlx4/main.c |  276 +++++++++++++++++++++++++++++++++----
 drivers/net/mlx4/cmd.c            |    6 +
 drivers/net/mlx4/en_main.c        |   15 ++-
 drivers/net/mlx4/en_port.c        |    4 +-
 drivers/net/mlx4/en_port.h        |    3 +-
 drivers/net/mlx4/intf.c           |   20 +++
 drivers/net/mlx4/main.c           |    6 +
 drivers/net/mlx4/mlx4.h           |    1 +
 include/linux/mlx4/cmd.h          |    1 +
 include/linux/mlx4/driver.h       |   16 ++-
 10 files changed, 310 insertions(+), 38 deletions(-)

diff --git a/drivers/infiniband/hw/mlx4/main.c 
b/drivers/infiniband/hw/mlx4/main.c
index ae3d759..40442b8 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/netdevice.h>
 
 #include <rdma/ib_smi.h>
 #include <rdma/ib_user_verbs.h>
@@ -152,28 +153,19 @@ out:
        return err;
 }
 
-static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
-                             struct ib_port_attr *props)
+static enum ib_port_link_type mlx4_ib_get_port_link_type(struct ib_device 
*device,
+                                                        u8 port_num)
 {
-       struct ib_smp *in_mad  = NULL;
-       struct ib_smp *out_mad = NULL;
-       int err = -ENOMEM;
-
-       in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
-       out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
-       if (!in_mad || !out_mad)
-               goto out;
-
-       memset(props, 0, sizeof *props);
-
-       init_query_mad(in_mad);
-       in_mad->attr_id  = IB_SMP_ATTR_PORT_INFO;
-       in_mad->attr_mod = cpu_to_be32(port);
+       struct mlx4_dev *dev = to_mdev(device)->dev;
 
-       err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, 
out_mad);
-       if (err)
-               goto out;
+       return dev->caps.port_mask & (1 << (port_num - 1)) ?
+               PORT_LINK_IB : PORT_LINK_ETH;
+}
 
+static void ib_link_query_port(struct ib_device *ibdev, u8 port,
+                              struct ib_port_attr *props,
+                              struct ib_smp *out_mad)
+{
        props->lid              = be16_to_cpup((__be16 *) (out_mad->data + 16));
        props->lmc              = out_mad->data[34] & 0x7;
        props->sm_lid           = be16_to_cpup((__be16 *) (out_mad->data + 18));
@@ -193,6 +185,67 @@ static int mlx4_ib_query_port(struct ib_device *ibdev, u8 
port,
        props->subnet_timeout   = out_mad->data[51] & 0x1f;
        props->max_vl_num       = out_mad->data[37] >> 4;
        props->init_type_reply  = out_mad->data[41] >> 4;
+       props->link_type        = PORT_LINK_IB;
+}
+
+static void eth_link_query_port(struct ib_device *ibdev, u8 port,
+                               struct ib_port_attr *props,
+                               struct ib_smp *out_mad)
+{
+       struct mlx4_ib_rdmaoe *rdmaoe = &to_mdev(ibdev)->rdmaoe;
+       struct net_device *ndev;
+
+       props->port_cap_flags   = be32_to_cpup((__be32 *) (out_mad->data + 20));
+       props->gid_tbl_len      = to_mdev(ibdev)->dev->caps.gid_table_len[port];
+       props->max_msg_sz       = to_mdev(ibdev)->dev->caps.max_msg_sz;
+       props->pkey_tbl_len     = 
to_mdev(ibdev)->dev->caps.pkey_table_len[port];
+       props->bad_pkey_cntr    = be16_to_cpup((__be16 *) (out_mad->data + 46));
+       props->qkey_viol_cntr   = be16_to_cpup((__be16 *) (out_mad->data + 48));
+       props->active_width     = out_mad->data[31] & 0xf;
+       props->active_speed     = out_mad->data[35] >> 4;
+       props->max_mtu          = out_mad->data[41] & 0xf;
+       props->active_mtu       = rdmaoe->mtu[port - 1];
+       props->subnet_timeout   = out_mad->data[51] & 0x1f;
+       props->max_vl_num       = out_mad->data[37] >> 4;
+       props->init_type_reply  = out_mad->data[41] >> 4;
+       props->link_type        = PORT_LINK_ETH;
+       spin_lock(&rdmaoe->lock);
+       ndev = rdmaoe->netdevs[port - 1];
+       if (!ndev)
+               goto out;
+
+       props->state            = netif_running(ndev) &&  netif_oper_up(ndev) ?
+                                       IB_PORT_ACTIVE : IB_PORT_DOWN;
+       props->phys_state       = props->state;
+out:
+       spin_unlock(&rdmaoe->lock);
+}
+
+static int mlx4_ib_query_port(struct ib_device *ibdev, u8 port,
+                             struct ib_port_attr *props)
+{
+       struct ib_smp *in_mad  = NULL;
+       struct ib_smp *out_mad = NULL;
+       int err = -ENOMEM;
+
+       in_mad  = kzalloc(sizeof *in_mad, GFP_KERNEL);
+       out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL);
+       if (!in_mad || !out_mad)
+               goto out;
+
+       memset(props, 0, sizeof *props);
+
+       init_query_mad(in_mad);
+       in_mad->attr_id  = IB_SMP_ATTR_PORT_INFO;
+       in_mad->attr_mod = cpu_to_be32(port);
+
+       err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, 
out_mad);
+       if (err)
+               goto out;
+
+       mlx4_ib_get_port_link_type(ibdev, port) == PORT_LINK_IB ?
+               ib_link_query_port(ibdev, port, props, out_mad) :
+               eth_link_query_port(ibdev, port, props, out_mad);
 
 out:
        kfree(in_mad);
@@ -287,6 +340,7 @@ static int mlx4_SET_PORT(struct mlx4_ib_dev *dev, u8 port, 
int reset_qkey_viols,
 {
        struct mlx4_cmd_mailbox *mailbox;
        int err;
+       u8 is_eth = dev->dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH;
 
        mailbox = mlx4_alloc_cmd_mailbox(dev->dev);
        if (IS_ERR(mailbox))
@@ -302,7 +356,7 @@ static int mlx4_SET_PORT(struct mlx4_ib_dev *dev, u8 port, 
int reset_qkey_viols,
                ((__be32 *) mailbox->buf)[1] = cpu_to_be32(cap_mask);
        }
 
-       err = mlx4_cmd(dev->dev, mailbox->dma, port, 0, MLX4_CMD_SET_PORT,
+       err = mlx4_cmd(dev->dev, mailbox->dma, port, is_eth, MLX4_CMD_SET_PORT,
                       MLX4_CMD_TIME_CLASS_B);
 
        mlx4_free_cmd_mailbox(dev->dev, mailbox);
@@ -538,19 +592,153 @@ static struct device_attribute *mlx4_class_attributes[] 
= {
        &dev_attr_board_id
 };
 
+static void mlx4_addrconf_ifid_eui48(u8 *eui, struct net_device *dev)
+{
+       memcpy(eui, dev->dev_addr, 3);
+       memcpy(eui + 5, dev->dev_addr + 3, 3);
+       eui[3] = 0xFF;
+       eui[4] = 0xFE;
+       eui[0] ^= 2;
+}
+
+static int update_ipv6_gids(struct mlx4_ib_dev *dev, int port, int clear)
+{
+       struct net_device *ndev = dev->rdmaoe.netdevs[port - 1];
+       struct mlx4_cmd_mailbox *mailbox;
+       union ib_gid *gids, *tmpgids;
+       int err;
+
+       tmpgids = kzalloc(128 * sizeof *gids, GFP_ATOMIC);
+       if (!tmpgids)
+               return -ENOMEM;
+
+       if (!clear) {
+               mlx4_addrconf_ifid_eui48(&tmpgids[0].raw[8], ndev);
+               tmpgids[0].global.subnet_prefix = 
cpu_to_be64(0xfe80000000000000LL);
+       }
+       spin_unlock(&dev->rdmaoe.lock);
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev->dev);
+       if (IS_ERR(mailbox)) {
+               err = PTR_ERR(mailbox);
+               goto out;
+       }
+
+       gids = mailbox->buf;
+       memcpy(gids, tmpgids, 128 * sizeof *gids);
+
+       err = mlx4_cmd(dev->dev, mailbox->dma, MLX4_SET_PORT_GID_TABLE << 8 | 
port,
+                      1, MLX4_CMD_SET_PORT, MLX4_CMD_TIME_CLASS_B);
+
+       mlx4_free_cmd_mailbox(dev->dev, mailbox);
+
+out:
+       kfree(tmpgids);
+       spin_lock(&dev->rdmaoe.lock);
+       return err;
+}
+
+static void update_mtu(struct mlx4_ib_dev *dev, int port)
+{
+       struct net_device *ndev = dev->rdmaoe.netdevs[port - 1];
+
+       if (ndev->mtu >= 4096)
+               dev->rdmaoe.mtu[port - 1] = IB_MTU_4096;
+       else if (ndev->mtu >= 2048)
+               dev->rdmaoe.mtu[port - 1] = IB_MTU_2048;
+       else if (ndev->mtu >= 1024)
+               dev->rdmaoe.mtu[port - 1] = IB_MTU_1024;
+       else if (ndev->mtu >= 512)
+               dev->rdmaoe.mtu[port - 1] = IB_MTU_512;
+       else if (ndev->mtu >= 256)
+               dev->rdmaoe.mtu[port - 1] = IB_MTU_256;
+       else {
+               printk(KERN_WARNING "Eth MTU %d too small - IB may not work 
properly\n",
+                      ndev->mtu);
+               dev->rdmaoe.mtu[port - 1] = IB_MTU_256;
+       }
+}
+
+static void handle_en_event(struct mlx4_ib_dev *dev, int port, unsigned long 
event)
+{
+       switch (event) {
+       case NETDEV_UP:
+               update_ipv6_gids(dev, port, 0);
+               break;
+
+       case NETDEV_DOWN:
+               update_ipv6_gids(dev, port, 1);
+
+       case NETDEV_CHANGEMTU:
+               update_mtu(dev, port);
+               break;
+       }
+}
+
+static void netdev_added(struct mlx4_ib_dev *dev, int port)
+{
+       update_ipv6_gids(dev, port, 0);
+       update_mtu(dev, port);
+}
+
+static void netdev_removed(struct mlx4_ib_dev *dev, int port)
+{
+       update_ipv6_gids(dev, port, 1);
+}
+
+static int mlx4_ib_netdev_event(struct notifier_block *this, unsigned long 
event,
+                               void *ptr)
+{
+       struct net_device *dev = ptr;
+       struct mlx4_ib_dev *ibdev;
+       struct net_device *oldnd;
+       struct mlx4_ib_rdmaoe *rdmaoe;
+       int port;
+
+       if (!net_eq(dev_net(dev), &init_net))
+               return NOTIFY_DONE;
+
+       ibdev = container_of(this, struct mlx4_ib_dev, rdmaoe.nb);
+       rdmaoe = &ibdev->rdmaoe;
+
+       spin_lock(&rdmaoe->lock);
+       mlx4_foreach_ib_transport_port(port, ibdev->dev) {
+               oldnd = rdmaoe->netdevs[port - 1];
+               rdmaoe->netdevs[port - 1] = mlx4_get_prot_dev(ibdev->dev, 
MLX4_PROT_EN, port);
+               if (oldnd != rdmaoe->netdevs[port - 1]) {
+                       if (rdmaoe->netdevs[port - 1])
+                               netdev_added(ibdev, port);
+                       else
+                               netdev_removed(ibdev, port);
+               }
+       }
+
+       if (dev == rdmaoe->netdevs[0])
+               handle_en_event(ibdev, 1, event);
+       else if (dev == rdmaoe->netdevs[1])
+               handle_en_event(ibdev, 2, event);
+
+       spin_unlock(&rdmaoe->lock);
+
+       return NOTIFY_DONE;
+}
+
 static void *mlx4_ib_add(struct mlx4_dev *dev)
 {
        static int mlx4_ib_version_printed;
        struct mlx4_ib_dev *ibdev;
        int num_ports = 0;
        int i;
+       int err;
+       int port;
+       struct mlx4_ib_rdmaoe *rdmaoe;
 
        if (!mlx4_ib_version_printed) {
                printk(KERN_INFO "%s", mlx4_ib_version);
                ++mlx4_ib_version_printed;
        }
 
-       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
+       mlx4_foreach_ib_transport_port(i, dev)
                num_ports++;
 
        /* No point in registering a device with no ports... */
@@ -563,6 +751,8 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
                return NULL;
        }
 
+       rdmaoe = &ibdev->rdmaoe;
+
        if (mlx4_pd_alloc(dev, &ibdev->priv_pdn))
                goto err_dealloc;
 
@@ -607,10 +797,12 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
                (1ull << IB_USER_VERBS_CMD_CREATE_SRQ)          |
                (1ull << IB_USER_VERBS_CMD_MODIFY_SRQ)          |
                (1ull << IB_USER_VERBS_CMD_QUERY_SRQ)           |
-               (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ);
+               (1ull << IB_USER_VERBS_CMD_DESTROY_SRQ)         |
+               (1ull << IB_USER_VERBS_CMD_GET_MAC);
 
        ibdev->ib_dev.query_device      = mlx4_ib_query_device;
        ibdev->ib_dev.query_port        = mlx4_ib_query_port;
+       ibdev->ib_dev.get_port_link_type = mlx4_ib_get_port_link_type;
        ibdev->ib_dev.query_gid         = mlx4_ib_query_gid;
        ibdev->ib_dev.query_pkey        = mlx4_ib_query_pkey;
        ibdev->ib_dev.modify_device     = mlx4_ib_modify_device;
@@ -654,15 +846,26 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
        ibdev->ib_dev.map_phys_fmr      = mlx4_ib_map_phys_fmr;
        ibdev->ib_dev.unmap_fmr         = mlx4_ib_unmap_fmr;
        ibdev->ib_dev.dealloc_fmr       = mlx4_ib_fmr_dealloc;
+       ibdev->ib_dev.get_mac           = mlx4_ib_get_mac;
+
+       mlx4_foreach_ib_transport_port(port, dev)
+               rdmaoe->netdevs[port - 1] = mlx4_get_prot_dev(dev, 
MLX4_PROT_EN, port);
+       spin_lock_init(&rdmaoe->lock);
+       if (dev->caps.flags & MLX4_DEV_CAP_FLAG_RDMAOE && 
!rdmaoe->nb.notifier_call) {
+               rdmaoe->nb.notifier_call = mlx4_ib_netdev_event;
+               err = register_netdevice_notifier(&rdmaoe->nb);
+               if (err)
+                       goto err_map;
+       }
 
        if (init_node_data(ibdev))
-               goto err_map;
+               goto err_notif;
 
        spin_lock_init(&ibdev->sm_lock);
        mutex_init(&ibdev->cap_mask_mutex);
 
        if (ib_register_device(&ibdev->ib_dev))
-               goto err_map;
+               goto err_notif;
 
        if (mlx4_ib_mad_init(ibdev))
                goto err_reg;
@@ -678,6 +881,9 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
 err_reg:
        ib_unregister_device(&ibdev->ib_dev);
 
+err_notif:
+       unregister_netdevice_notifier(&rdmaoe->nb);
+
 err_map:
        iounmap(ibdev->uar_map);
 
@@ -700,11 +906,15 @@ static void mlx4_ib_remove(struct mlx4_dev *dev, void 
*ibdev_ptr)
 
        mlx4_ib_mad_cleanup(ibdev);
        ib_unregister_device(&ibdev->ib_dev);
+       if (ibdev->rdmaoe.nb.notifier_call) {
+               unregister_netdevice_notifier(&ibdev->rdmaoe.nb);
+               ibdev->rdmaoe.nb.notifier_call = NULL;
+       }
+       iounmap(ibdev->uar_map);
 
-       for (p = 1; p <= ibdev->num_ports; ++p)
+       mlx4_foreach_port(p, dev, MLX4_PORT_TYPE_IB)
                mlx4_CLOSE_PORT(dev, p);
 
-       iounmap(ibdev->uar_map);
        mlx4_uar_free(dev, &ibdev->priv_uar);
        mlx4_pd_free(dev, ibdev->priv_pdn);
        ib_dealloc_device(&ibdev->ib_dev);
@@ -745,17 +955,27 @@ static void mlx4_ib_event(struct mlx4_dev *dev, void 
*ibdev_ptr,
 static struct mlx4_interface mlx4_ib_interface = {
        .add    = mlx4_ib_add,
        .remove = mlx4_ib_remove,
-       .event  = mlx4_ib_event
+       .event  = mlx4_ib_event,
+       .protocol       = MLX4_PROT_IB
 };
 
 static int __init mlx4_ib_init(void)
 {
-       return mlx4_register_interface(&mlx4_ib_interface);
+       int err;
+
+       mlx4_ib_addr_init();
+
+       err = mlx4_register_interface(&mlx4_ib_interface);
+       if (err)
+               mlx4_ib_addr_cleanup();
+
+       return err;
 }
 
 static void __exit mlx4_ib_cleanup(void)
 {
        mlx4_unregister_interface(&mlx4_ib_interface);
+       mlx4_ib_addr_cleanup();
 }
 
 module_init(mlx4_ib_init);
diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c
index 2845a05..07a646b 100644
--- a/drivers/net/mlx4/cmd.c
+++ b/drivers/net/mlx4/cmd.c
@@ -103,6 +103,7 @@ enum {
 struct mlx4_cmd_context {
        struct completion       done;
        int                     result;
+       u16                     command;
        int                     next;
        u64                     out_param;
        u16                     token;
@@ -255,6 +256,10 @@ void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 
status, u64 out_param)
                return;
 
        context->result    = mlx4_status_to_errno(status);
+       if (context->result)
+               mlx4_warn(dev, "FW command 0x%x failed with FW status = %d\n",
+                         context->command, status);
+
        context->out_param = out_param;
 
        complete(&context->done);
@@ -274,6 +279,7 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 
in_param, u64 *out_param,
        BUG_ON(cmd->free_head < 0);
        context = &cmd->context[cmd->free_head];
        context->token += cmd->token_mask + 1;
+       context->command = op;
        cmd->free_head = context->next;
        spin_unlock(&cmd->context_lock);
 
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 510633f..6f30eca 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -51,6 +51,13 @@ static const char mlx4_en_version[] =
        DRV_NAME ": Mellanox ConnectX HCA Ethernet driver v"
        DRV_VERSION " (" DRV_RELDATE ")\n";
 
+static void *get_netdev(struct mlx4_dev *dev, void *ctx, u8 port)
+{
+       struct mlx4_en_dev *endev = ctx;
+
+       return endev->pndev[port];
+}
+
 static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr,
                          enum mlx4_dev_event event, int port)
 {
@@ -229,9 +236,11 @@ err_free_res:
 }
 
 static struct mlx4_interface mlx4_en_interface = {
-       .add    = mlx4_en_add,
-       .remove = mlx4_en_remove,
-       .event  = mlx4_en_event,
+       .add            = mlx4_en_add,
+       .remove         = mlx4_en_remove,
+       .event          = mlx4_en_event,
+       .get_prot_dev   = get_netdev,
+       .protocol       = MLX4_PROT_EN,
 };
 
 static int __init mlx4_en_init(void)
diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c
index a29abe8..a249887 100644
--- a/drivers/net/mlx4/en_port.c
+++ b/drivers/net/mlx4/en_port.c
@@ -127,8 +127,8 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, 
u32 base_qpn,
        memset(context, 0, sizeof *context);
 
        context->base_qpn = cpu_to_be32(base_qpn);
-       context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT | 
base_qpn);
-       context->mcast = cpu_to_be32(1 << SET_PORT_PROMISC_SHIFT | base_qpn);
+       context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_EN_SHIFT | 
base_qpn);
+       context->mcast = cpu_to_be32(1 << SET_PORT_PROMISC_MODE_SHIFT | 
base_qpn);
        context->intra_no_vlan = 0;
        context->no_vlan = MLX4_NO_VLAN_IDX;
        context->intra_vlan_miss = 0;
diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h
index e6477f1..9354891 100644
--- a/drivers/net/mlx4/en_port.h
+++ b/drivers/net/mlx4/en_port.h
@@ -36,7 +36,8 @@
 
 
 #define SET_PORT_GEN_ALL_VALID 0x7
-#define SET_PORT_PROMISC_SHIFT 31
+#define SET_PORT_PROMISC_EN_SHIFT      31
+#define SET_PORT_PROMISC_MODE_SHIFT    30
 
 enum {
        MLX4_CMD_SET_VLAN_FLTR  = 0x47,
diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c
index 0e7eb10..d64530e 100644
--- a/drivers/net/mlx4/intf.c
+++ b/drivers/net/mlx4/intf.c
@@ -159,3 +159,23 @@ void mlx4_unregister_device(struct mlx4_dev *dev)
 
        mutex_unlock(&intf_mutex);
 }
+
+void *mlx4_find_get_prot_dev(struct mlx4_dev *dev, enum mlx4_prot proto, int 
port)
+{
+       struct mlx4_priv *priv = mlx4_priv(dev);
+       struct mlx4_device_context *dev_ctx;
+       unsigned long flags;
+       void *result = NULL;
+
+       spin_lock_irqsave(&priv->ctx_lock, flags);
+
+       list_for_each_entry(dev_ctx, &priv->ctx_list, list)
+               if (dev_ctx->intf->protocol == proto && 
dev_ctx->intf->get_prot_dev) {
+                       result = dev_ctx->intf->get_prot_dev(dev, 
dev_ctx->context, port);
+                       break;
+               }
+
+       spin_unlock_irqrestore(&priv->ctx_lock, flags);
+
+       return result;
+}
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 30bea96..c72af51 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -100,6 +100,12 @@ module_param_named(use_prio, use_prio, bool, 0444);
 MODULE_PARM_DESC(use_prio, "Enable steering by VLAN priority on ETH ports "
                  "(0/1, default 0)");
 
+void *mlx4_get_prot_dev(struct mlx4_dev *dev, enum mlx4_prot proto, int port)
+{
+       return mlx4_find_get_prot_dev(dev, proto, port);
+}
+EXPORT_SYMBOL(mlx4_get_prot_dev);
+
 int mlx4_check_port_params(struct mlx4_dev *dev,
                           enum mlx4_port_type *port_type)
 {
diff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h
index 5bd79c2..db068c9 100644
--- a/drivers/net/mlx4/mlx4.h
+++ b/drivers/net/mlx4/mlx4.h
@@ -364,6 +364,7 @@ int mlx4_restart_one(struct pci_dev *pdev);
 int mlx4_register_device(struct mlx4_dev *dev);
 void mlx4_unregister_device(struct mlx4_dev *dev);
 void mlx4_dispatch_event(struct mlx4_dev *dev, enum mlx4_dev_event type, int 
port);
+void *mlx4_find_get_prot_dev(struct mlx4_dev *dev, enum mlx4_prot proto, int 
port);
 
 struct mlx4_dev_cap;
 struct mlx4_init_hca_param;
diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h
index 0f82293..22bd8d3 100644
--- a/include/linux/mlx4/cmd.h
+++ b/include/linux/mlx4/cmd.h
@@ -140,6 +140,7 @@ enum {
        MLX4_SET_PORT_MAC_TABLE = 0x2,
        MLX4_SET_PORT_VLAN_TABLE = 0x3,
        MLX4_SET_PORT_PRIO_MAP  = 0x4,
+       MLX4_SET_PORT_GID_TABLE = 0x5,
 };
 
 struct mlx4_dev;
diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h
index 53c5fdb..0083256 100644
--- a/include/linux/mlx4/driver.h
+++ b/include/linux/mlx4/driver.h
@@ -44,15 +44,23 @@ enum mlx4_dev_event {
        MLX4_DEV_EVENT_PORT_REINIT,
 };
 
+enum mlx4_prot {
+       MLX4_PROT_IB,
+       MLX4_PROT_EN,
+};
+
 struct mlx4_interface {
-       void *                  (*add)   (struct mlx4_dev *dev);
-       void                    (*remove)(struct mlx4_dev *dev, void *context);
-       void                    (*event) (struct mlx4_dev *dev, void *context,
-                                         enum mlx4_dev_event event, int port);
+       void *  (*add)   (struct mlx4_dev *dev);
+       void    (*remove)(struct mlx4_dev *dev, void *context);
+       void    (*event) (struct mlx4_dev *dev, void *context,
+                         enum mlx4_dev_event event, int port);
+       void *  (*get_prot_dev) (struct mlx4_dev *dev, void *context, u8 port);
+       enum mlx4_prot          protocol;
        struct list_head        list;
 };
 
 int mlx4_register_interface(struct mlx4_interface *intf);
 void mlx4_unregister_interface(struct mlx4_interface *intf);
+void *mlx4_get_prot_dev(struct mlx4_dev *dev, enum mlx4_prot proto, int port);
 
 #endif /* MLX4_DRIVER_H */
-- 
1.6.3.3

_______________________________________________
general mailing list
general@lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to