mlx4: Initialize ConnectX core driver (mlx4_core)
authorXiao Jia <stfairy@gmail.com>
Thu, 17 Sep 2015 01:19:20 +0000 (18:19 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 23 Sep 2015 20:46:27 +0000 (16:46 -0400)
kern/drivers/net/mlx4/eq.c
kern/drivers/net/mlx4/main.c

index 808a3d7..8c87a70 100644 (file)
@@ -830,6 +830,16 @@ static void mlx4_msi_x_interrupt(struct hw_trapframe *hw_tf, void *eq_ptr)
 }
 #endif
 
+static void mlx4_msi_x_interrupt_akaros(struct hw_trapframe *hw_tf, void *data)
+{
+       struct mlx4_eq  *eq = data;
+       struct mlx4_dev *dev = eq ? eq->dev : 0;
+
+       if (!eq || !dev)
+               panic("!eq || !dev");
+       mlx4_eq_int(dev, eq);
+}
+
 int mlx4_MAP_EQ_wrapper(struct mlx4_dev *dev, int slave,
                        struct mlx4_vhcr *vhcr,
                        struct mlx4_cmd_mailbox *inbox,
@@ -1251,6 +1261,11 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
                                           mlx4_msi_x_interrupt,
                                           priv->eq_table.eq + i,
                                           pci_to_tbdf(PCIDEV));
+#else
+                       err = register_irq(priv->eq_table.eq[i].irq,
+                                          mlx4_msi_x_interrupt_akaros,
+                                          priv->eq_table.eq + i,
+                                          pci_to_tbdf(dev->persist->pdev));
 #endif
                        if (err)
                                goto err_out_async;
index 0f450f9..24a99b7 100644 (file)
@@ -2379,6 +2379,7 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
                if (dev->flags & MLX4_FLAG_MSI_X) {
                        mlx4_warn(dev, "NOP command failed to generate MSI-X interrupt IRQ %d)\n",
                                  priv->eq_table.eq[dev->caps.num_comp_vectors].irq);
+                       panic("MSI-X required");
                        mlx4_warn(dev, "Trying again without MSI-X\n");
                } else {
                        mlx4_err(dev, "NOP command failed to generate interrupt (IRQ %d), aborting\n",
@@ -2545,6 +2546,17 @@ no_msi:
 
        for (i = 0; i < 2; ++i)
                priv->eq_table.eq[i].irq = dev->persist->pdev->irq;
+#else
+       if (!msi_x)
+               panic("!msi_x");
+
+       if (pci_msix_init(dev->persist->pdev) == -1)
+               panic("pci_msix_init -1");
+
+       dev->caps.comp_pool = 0;
+       dev->caps.num_comp_vectors = 1;
+
+       dev->flags |= MLX4_FLAG_MSI_X;
 #endif
 }
 
@@ -3233,6 +3245,7 @@ static int __mlx4_init_one(struct pci_device *pdev, int pci_dev_data,
        unsigned int i;
 
        pr_info(DRV_NAME ": Initializing %s\n", pci_name(pdev));
+       pcidev_print_info(pdev, 1 /* verbose */);
 
        err = pci_enable_device(pdev);
        if (err) {
@@ -3820,4 +3833,77 @@ static void __exit mlx4_cleanup(void)
 
 module_init(mlx4_init);
 module_exit(mlx4_cleanup);
+#else
+/* Network driver stub for mlx4 */
+
+#include <vfs.h>
+#include <kfs.h>
+#include <slab.h>
+#include <kmalloc.h>
+#include <kref.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <error.h>
+#include <cpio.h>
+#include <pmap.h>
+#include <smp.h>
+#include <arch/pci.h>
+#include <ip.h>
+#include <ns.h>
+
+static const struct pci_device_id *search_pci_table(struct pci_device *needle)
+{
+       const struct pci_device_id *i;
+
+       for (i = mlx4_pci_table; i->vendor; i++) {
+               if (needle->ven_id == i->vendor && needle->dev_id == i->device)
+                       break;
+       }
+       if (i->vendor)
+               return i;
+
+       return NULL;
+}
+
+/* Called by devether's probe routines.  Return -1 if the edev does not match
+ * any of your ctlrs. */
+static int mlx4_pnp(struct ether *edev)
+{
+       static bool probed = false; // TODO support multiple devices
+
+       const struct pci_device_id *pci_id;
+       struct pci_device *pdev;
+
+       if (probed)
+               return -1;
+       probed = true;
+
+       STAILQ_FOREACH(pdev, &pci_devices, all_dev) {
+               /* This checks that pcidev is a Network Controller for Ethernet */
+               if (pdev->class != 0x02 || pdev->subclass != 0x00)
+                       continue;
+
+               pci_id = search_pci_table(pdev);
+               if (!pci_id)
+                       continue;
+
+               printk("mlx4 driver found 0x%04x:%04x at %02x:%02x.%x\n",
+                      pdev->ven_id, pdev->dev_id, pdev->bus, pdev->dev,
+                      pdev->func);
+               break;
+       }
+       if (!pci_id)
+               return -1;
+
+       mlx4_init();
+       mlx4_init_one(pdev, pci_id);
+
+       return 0;
+}
+
+linker_func_3(ethermlx4_link)
+{
+       addethercard("mlx4", mlx4_pnp);
+}
 #endif