]> Pileus Git - ~andy/linux/blobdiff - drivers/net/ethernet/mellanox/mlx4/port.c
Merge branch 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~andy/linux] / drivers / net / ethernet / mellanox / mlx4 / port.c
index b7c4c083dffc7ae396d78df65fabf42baacd1f7a..d942aea4927b1aa1b9ec67ddd703d2227a290fee 100644 (file)
@@ -149,22 +149,26 @@ int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *qpn, u8 wrap)
 
        if (dev->caps.flags & MLX4_DEV_CAP_FLAG_VEP_UC_STEER) {
                err = mlx4_uc_steer_add(dev, port, mac, qpn, 1);
-               if (!err) {
-                       entry = kmalloc(sizeof *entry, GFP_KERNEL);
-                       if (!entry) {
-                               mlx4_uc_steer_release(dev, port, mac, *qpn, 1);
-                               return -ENOMEM;
-                       }
-                       entry->mac = mac;
-                       err = radix_tree_insert(&info->mac_tree, *qpn, entry);
-                       if (err) {
-                               mlx4_uc_steer_release(dev, port, mac, *qpn, 1);
-                               return err;
-                       }
-               } else
+               if (err)
                        return err;
+
+               entry = kmalloc(sizeof *entry, GFP_KERNEL);
+               if (!entry) {
+                       mlx4_uc_steer_release(dev, port, mac, *qpn, 1);
+                       return -ENOMEM;
+               }
+
+               entry->mac = mac;
+               err = radix_tree_insert(&info->mac_tree, *qpn, entry);
+               if (err) {
+                       kfree(entry);
+                       mlx4_uc_steer_release(dev, port, mac, *qpn, 1);
+                       return err;
+               }
        }
+
        mlx4_dbg(dev, "Registering MAC: 0x%llx\n", (unsigned long long) mac);
+
        mutex_lock(&table->mutex);
        for (i = 0; i < MLX4_MAX_MAC_NUM - 1; i++) {
                if (free < 0 && !table->refs[i]) {
@@ -466,6 +470,48 @@ int mlx4_get_port_ib_caps(struct mlx4_dev *dev, u8 port, __be32 *caps)
        return err;
 }
 
+int mlx4_check_ext_port_caps(struct mlx4_dev *dev, u8 port)
+{
+       struct mlx4_cmd_mailbox *inmailbox, *outmailbox;
+       u8 *inbuf, *outbuf;
+       int err, packet_error;
+
+       inmailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(inmailbox))
+               return PTR_ERR(inmailbox);
+
+       outmailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(outmailbox)) {
+               mlx4_free_cmd_mailbox(dev, inmailbox);
+               return PTR_ERR(outmailbox);
+       }
+
+       inbuf = inmailbox->buf;
+       outbuf = outmailbox->buf;
+       memset(inbuf, 0, 256);
+       memset(outbuf, 0, 256);
+       inbuf[0] = 1;
+       inbuf[1] = 1;
+       inbuf[2] = 1;
+       inbuf[3] = 1;
+
+       *(__be16 *) (&inbuf[16]) = MLX4_ATTR_EXTENDED_PORT_INFO;
+       *(__be32 *) (&inbuf[20]) = cpu_to_be32(port);
+
+       err = mlx4_cmd_box(dev, inmailbox->dma, outmailbox->dma, port, 3,
+                          MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C);
+
+       packet_error = be16_to_cpu(*(__be16 *) (outbuf + 4));
+
+       dev->caps.ext_port_cap[port] = (!err && !packet_error) ?
+                                      MLX_EXT_PORT_CAP_FLAG_EXTENDED_PORT_INFO
+                                      : 0;
+
+       mlx4_free_cmd_mailbox(dev, inmailbox);
+       mlx4_free_cmd_mailbox(dev, outmailbox);
+       return err;
+}
+
 int mlx4_SET_PORT(struct mlx4_dev *dev, u8 port)
 {
        struct mlx4_cmd_mailbox *mailbox;