BXE: attach

Attaches in the reset/pnp (at boot time).

There's still a lot of obvious stuff that's not hooked up.  Grep XME.
diff --git a/kern/drivers/net/bxe/bxe.c b/kern/drivers/net/bxe/bxe.c
index c9f9303..3f70e45 100644
--- a/kern/drivers/net/bxe/bxe.c
+++ b/kern/drivers/net/bxe/bxe.c
@@ -251,6 +251,7 @@
 
 #endif
 qlock_t bxe_prev_mtx;
+struct bxe_prev_list bxe_prev_list = LIST_HEAD_INITIALIZER(bxe_prev_list);
 
 struct bxe_prev_list_node {
     LIST_ENTRY(bxe_prev_list_node) node;
@@ -4845,7 +4846,7 @@
         BLOGD(sc, DBG_IOCTL,
               "Received SIOCSIFMEDIA/SIOCGIFMEDIA ioctl (cmd=%lu)\n",
               (command & 0xff));
-        error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command);
+        error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
         break;
 
     case SIOCGPRIVATE_0:
@@ -9228,6 +9229,8 @@
 static int
 bxe_interrupt_alloc(struct bxe_adapter *sc)
 {
+		// XME
+    return 0;
 #if 0
     int msix_count = 0;
     int msi_count = 0;
@@ -9418,7 +9421,6 @@
 
     return (rc);
 #endif
-    return -1;
 }
 
 static void
@@ -13298,7 +13300,6 @@
 {
     unsigned int flags;
     int i;
-#if 0
     memset(sc->bar, 0, sizeof(sc->bar));
 
     for (i = 0; i < MAX_BARS; i++) {
@@ -13306,11 +13307,36 @@
         /* memory resources reside at BARs 0, 2, 4 */
         /* Run `pciconf -lb` to see mappings */
         if ((i != 0) && (i != 2) && (i != 4)) {
+			/* i guess sc->bar[1] is just 0s */
             continue;
         }
 
         sc->bar[i].rid = PCIR_BAR(i);
 
+		/* The bar handles are supposed to be KVAs - they get dereferenced
+		 * later.  The addrs in the pcidev->bar are physical addrs.  For now,
+		 * we just map bar 0 and have it in sc->mmio. */
+		if (i == 0) {
+			sc->bar[i].tag = X86_BUS_SPACE_MEM;
+        	sc->bar[i].handle = (uintptr_t)sc->mmio;
+		} else {
+			sc->bar[i].tag = X86_BUS_SPACE_MEM;
+        	sc->bar[i].handle = 0xcafeface;
+		}
+
+		/* Maybe do something like this:
+        sc->bar[i].handle = pci_get_membar(sc->pcidev, i);
+		if (sc->bar[i].handle) {
+			sc->bar[i].tag = X86_BUS_SPACE_MEM;
+		} else {
+        	sc->bar[i].handle = pci_get_iobar(sc->pcidev, i);
+			if (sc->bar[i].handle) {
+				sc->bar[i].tag = X86_BUS_SPACE_IO;
+			}
+		}
+		*/
+
+#if 0 /* BSD way */
         flags = RF_ACTIVE;
         if (i == 0) {
             flags |= RF_SHAREABLE;
@@ -13339,8 +13365,8 @@
               (void *)rman_get_end(sc->bar[i].resource),
               rman_get_size(sc->bar[i].resource),
               (void *)sc->bar[i].kva);
-    }
 #endif
+    }
     return (0);
 }
 
@@ -13447,6 +13473,7 @@
 static void
 bxe_probe_pci_caps(struct bxe_adapter *sc)
 {
+		// XXX XME 
 #if 0
     uint16_t link_status;
     int reg;
@@ -13989,6 +14016,7 @@
         BLOGD(sc, DBG_LOAD, "Ethernet address: %s\n", sc->mac_addr_str);
     }
 
+	// XME
 #if 0
     if (!IS_MF(sc) &&
         ((sc->port.config & PORT_FEAT_CFG_STORAGE_PERSONALITY_MASK) ==
@@ -14005,6 +14033,7 @@
     return (0);
 }
 
+// TODO XME XME
 static void
 bxe_get_tunable_params(struct bxe_adapter *sc)
 {
@@ -14115,49 +14144,46 @@
 static void
 bxe_media_detect(struct bxe_adapter *sc)
 {
-#if 0
     uint32_t phy_idx = bxe_get_cur_phy_idx(sc);
     switch (sc->link_params.phy[phy_idx].media_type) {
     case ELINK_ETH_PHY_SFPP_10G_FIBER:
     case ELINK_ETH_PHY_XFP_FIBER:
         BLOGI(sc, "Found 10Gb Fiber media.\n");
-        sc->media = IFM_10G_SR;
+        //sc->media = IFM_10G_SR;
         break;
     case ELINK_ETH_PHY_SFP_1G_FIBER:
         BLOGI(sc, "Found 1Gb Fiber media.\n");
-        sc->media = IFM_1000_SX;
+        //sc->media = IFM_1000_SX;
         break;
     case ELINK_ETH_PHY_KR:
     case ELINK_ETH_PHY_CX4:
         BLOGI(sc, "Found 10GBase-CX4 media.\n");
-        sc->media = IFM_10G_CX4;
+        //sc->media = IFM_10G_CX4;
         break;
     case ELINK_ETH_PHY_DA_TWINAX:
         BLOGI(sc, "Found 10Gb Twinax media.\n");
-        sc->media = IFM_10G_TWINAX;
+        //sc->media = IFM_10G_TWINAX;
         break;
     case ELINK_ETH_PHY_BASE_T:
         if (sc->link_params.speed_cap_mask[0] &
             PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
             BLOGI(sc, "Found 10GBase-T media.\n");
-            sc->media = IFM_10G_T;
+            //sc->media = IFM_10G_T;
         } else {
             BLOGI(sc, "Found 1000Base-T media.\n");
-            sc->media = IFM_1000_T;
+            //sc->media = IFM_1000_T;
         }
         break;
     case ELINK_ETH_PHY_NOT_PRESENT:
         BLOGI(sc, "Media not present.\n");
-        sc->media = 0;
+        //sc->media = 0;
         break;
     case ELINK_ETH_PHY_UNSPECIFIED:
     default:
         BLOGI(sc, "Unknown media!\n");
-        sc->media = 0;
+        //sc->media = 0;
         break;
     }
-#endif
-    assert(0);
 }
 
 #define GET_FIELD(value, fname)                     \
@@ -14376,7 +14402,7 @@
         (NVRAM_1MB_SIZE << (val & MCPR_NVM_CFG4_FLASH_SIZE));
     BLOGD(sc, DBG_LOAD, "nvram flash size: %d\n", sc->devinfo.flash_size);
 
-    /* get PCI capabilites */
+    /* get PCI capabilites */ // XME
     bxe_probe_pci_caps(sc);
 
     bxe_set_power_state(sc, PCI_PM_D0);
@@ -14385,6 +14411,7 @@
     bxe_get_shmem_info(sc);
 
     if (sc->devinfo.pcie_msix_cap_reg != 0) {
+			// XXX XME we need to do this XME
 	assert(0);
 //        val = pcidev_read16(sc->pcidev,
 //                              (sc->devinfo.pcie_msix_cap_reg +
@@ -14902,11 +14929,11 @@
                             NULL,                     /* lock() */
                             NULL,                     /* lock() arg */
                             &sc->parent_dma_tag);     /* returned dma tag */
-#endif
     if (rc != 0) {
         BLOGE(sc, "Failed to alloc parent DMA tag (%d)!\n", rc);
         return (1);
     }
+#endif
 
     /************************/
     /* DEFAULT STATUS BLOCK */
@@ -15938,6 +15965,12 @@
     return (rc);
 }
 
+static int bxe_prev_unload(struct bxe_adapter *sc)
+{
+	warn("BXE unload not supported");
+	return 0;
+}
+
 void
 bxe_dcbx_set_state(struct bxe_adapter *sc,
                    uint8_t          dcb_on,
@@ -16193,6 +16226,7 @@
         }
     }
 }
+#endif
 
 /*
  * Device attach function.
@@ -16204,28 +16238,25 @@
  * Returns:
  *   0 = Success, >0 = Failure
  */
-static int
-bxe_attach(struct bxe_adapter *sc)
+int bxe_attach(struct bxe_adapter *sc)
 {
-    struct bxe_adapter *sc;
-
-    sc = device_get_softc(dev);
+	struct pci_device *dev = sc->pcidev;
 
     BLOGD(sc, DBG_LOAD, "Starting attach...\n");
 
     sc->state = BXE_STATE_CLOSED;
 
-	// TODO: sc->pcidev  = /* SOMETHING */
-    sc->unit = device_get_unit(dev);
+	/* what is this? */
+    //sc->unit = device_get_unit(dev);
 
     BLOGD(sc, DBG_LOAD, "softc = %p\n", sc);
 
-    sc->pcie_bus    = pci_get_bus(dev);
-    sc->pcie_device = pci_get_slot(dev);
-    sc->pcie_func   = pci_get_function(dev);
+    sc->pcie_bus    = dev->bus;
+    sc->pcie_device = dev->dev;
+    sc->pcie_func   = dev->func;
 
     /* enable bus master capability */
-    pci_enable_busmaster(dev);
+    pci_set_bus_master(dev);
 
     /* get the BARs */
     if (bxe_allocate_bars(sc) != 0) {
@@ -16249,16 +16280,15 @@
     /* get device info and set params */
     if (bxe_get_device_info(sc) != 0) {
         BLOGE(sc, "getting device info\n");
-        bxe_deallocate_bars(sc);
-        pci_disable_busmaster(dev);
-        return (ENXIO);
+		/* assuming BSD wanted to free the mtx here too */
+		goto err_mux_bars_etc;
     }
 
     /* get final misc params */
     bxe_get_params(sc);
 
     /* set the default MTU (changed via ifconfig) */
-    sc->mtu = ETHERMTU;
+    sc->mtu = ETHERMAXTU;
 
     bxe_set_modes_bitmap(sc);
 
@@ -16271,51 +16301,21 @@
     bxe_get_phy_info(sc);
 
     /* initialize the FreeBSD ifnet interface */
-    if (bxe_init_ifnet(sc) != 0) {
-        bxe_release_mutexes(sc);
-        bxe_deallocate_bars(sc);
-        pci_disable_busmaster(dev);
-        return (ENXIO);
-    }
+    if (bxe_init_ifnet(sc) != 0)
+		goto err_mux_bars_etc;
 
+	// TODO XME
     /* allocate device interrupts */
-    if (bxe_interrupt_alloc(sc) != 0) {
-        if (sc->ifp != NULL) {
-            ether_ifdetach(sc->ifp);
-        }
-        ifmedia_removeall(&sc->ifmedia);
-        bxe_release_mutexes(sc);
-        bxe_deallocate_bars(sc);
-        pci_disable_busmaster(dev);
-        return (ENXIO);
-    }
+    if (bxe_interrupt_alloc(sc) != 0)
+		goto err_media_etc;
 
     /* allocate ilt */
-    if (bxe_alloc_ilt_mem(sc) != 0) {
-        bxe_interrupt_free(sc);
-        if (sc->ifp != NULL) {
-            ether_ifdetach(sc->ifp);
-        }
-        ifmedia_removeall(&sc->ifmedia);
-        bxe_release_mutexes(sc);
-        bxe_deallocate_bars(sc);
-        pci_disable_busmaster(dev);
-        return (ENXIO);
-    }
+    if (bxe_alloc_ilt_mem(sc) != 0)
+		goto err_interrupt_etc;
 
     /* allocate the host hardware/software hsi structures */
-    if (bxe_alloc_hsi_mem(sc) != 0) {
-        bxe_free_ilt_mem(sc);
-        bxe_interrupt_free(sc);
-        if (sc->ifp != NULL) {
-            ether_ifdetach(sc->ifp);
-        }
-        ifmedia_removeall(&sc->ifmedia);
-        bxe_release_mutexes(sc);
-        bxe_deallocate_bars(sc);
-        pci_disable_busmaster(dev);
-        return (ENXIO);
-    }
+    if (bxe_alloc_hsi_mem(sc) != 0)
+		goto err_ilt_mem_etc;
 
     /* need to reset chip if UNDI was active */
     if (IS_PF(sc) && !BXE_NOMCP(sc)) {
@@ -16349,11 +16349,26 @@
     sc->max_cos = 1;
     bxe_init_multi_cos(sc);
 
-    bxe_add_sysctls(sc);
-
     return (0);
+
+err_ilt_mem_etc:
+    bxe_free_ilt_mem(sc);
+err_interrupt_etc:
+    bxe_interrupt_free(sc);
+err_media_etc:
+    if (sc->ifp != NULL) {
+        //ether_ifdetach(sc->ifp);
+    }
+    ifmedia_removeall(&sc->media);
+err_mux_bars_etc:
+    bxe_release_mutexes(sc);
+    bxe_deallocate_bars(sc);
+    pci_clr_bus_master(dev);
+	warn("There was an error in attaching the BXE NIC");
+    return (ENXIO);
 }
 
+#if 0
 /*
  * Device detach function.
  *
@@ -16400,7 +16415,7 @@
     if (ifp != NULL) {
         ether_ifdetach(ifp);
     }
-    ifmedia_removeall(&sc->ifmedia);
+    ifmedia_removeall(&sc->media);
 
     /* XXX do the following based on driver state... */
 
diff --git a/kern/drivers/net/bxe/bxe.h b/kern/drivers/net/bxe/bxe.h
index 4b786a1..b89e58b 100644
--- a/kern/drivers/net/bxe/bxe.h
+++ b/kern/drivers/net/bxe/bxe.h
@@ -62,6 +62,8 @@
 #define if_getflags(netif) (netif)->feat
 #define if_setflags(sc)
 
+/* We don't do removal */
+#define ifmedia_removeall(x)
 
 #define MA_OWNED 0
 #define mtx_assert(lock, thing) assert(1)
@@ -417,7 +419,7 @@
 #define ETH_HLEN                  14
 #define ETH_OVERHEAD              (ETH_HLEN + 8 + 8)
 #define ETH_MIN_PACKET_SIZE       60
-#define ETH_MAX_PACKET_SIZE       ETHERMTU /* 1500 */
+#define ETH_MAX_PACKET_SIZE       ETHERMAXTU
 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
 /* TCP with Timestamp Option (32) + IPv6 (40) */
 #define ETH_MAX_TPA_HEADER_SIZE   72
@@ -439,6 +441,9 @@
     vm_offset_t        kva;
 };
 
+/* Not sure what this is, just identity mapping it. */
+#define PCIR_BAR(i) (i)
+
 struct bxe_intr {
     struct resource *resource;
     int             rid;
@@ -1117,8 +1122,8 @@
      *   B = Chip Bond ID  (bits 0-3)
      */
     uint32_t chip_id;
-#define CHIP_ID(sc)           0 /*((sc)->devinfo.chip_id & 0xffff0000)*/
-#define CHIP_NUM(sc)          0 /*((sc)->devinfo.chip_id >> 16)*/
+#define CHIP_ID(sc)           ((sc)->devinfo.chip_id & 0xffff0000)
+#define CHIP_NUM(sc)          ((sc)->devinfo.chip_id >> 16)
 /* device ids */
 #define CHIP_NUM_57710        0x164e
 #define CHIP_NUM_57711        0x164f
@@ -1315,6 +1320,7 @@
 	 * has a first element of 'void *if_softc' (which is us). XXX
 	 */
 	if_t 	    ifp;
+	LIST_ENTRY(bxe_adapter)		node;
 	/* OS defined structs */
 	struct net_device *netdev;
 	struct pci_device *pcidev;
@@ -1936,6 +1942,7 @@
 #error "Minimum DB doorbell stride is 8"
 #endif
 #define DPM_TRIGGER_TYPE 0x40
+/* This could be screwed up (BAR1 == 2) */
 #define DOORBELL(sc, cid, val)                                              \
     do {                                                                    \
         bus_space_write_4(sc->bar[BAR1].tag, sc->bar[BAR1].handle,          \
@@ -2268,6 +2275,8 @@
 
 /* Defined in bxe.c, init'd in bxereset or something in bxe_dev.c */
 extern qlock_t bxe_prev_mtx;
+LIST_HEAD(bxe_prev_list, bxe_adapter);
+extern struct bxe_prev_list bxe_prev_list;
 
 /***********/
 /* INLINES */
diff --git a/kern/drivers/net/bxe/bxe_dev.c b/kern/drivers/net/bxe/bxe_dev.c
index 11e87ed..da0fbb0 100644
--- a/kern/drivers/net/bxe/bxe_dev.c
+++ b/kern/drivers/net/bxe/bxe_dev.c
@@ -258,6 +258,10 @@
 
 	ctlr = edev->ctlr;
 	ctlr->edev = edev;	/* point back to Ether* */
+
+	/* not sure if we'll need/want any of the 9ns stuff */
+	return;
+
 	qlock(&ctlr->alock);
 	/* TODO: make sure we haven't attached already.  If so, just return */
 
@@ -308,7 +312,12 @@
 {
 	int ctrl, i, pause, r, swdpio, txcw;
 
-	run_once(qlock_init(&bxe_prev_mtx));
+	/* despite the name, we attach at reset time.  BXE attach has a lot of
+	 * mmio mappings that have to happen at boot (in akaros), instead of during
+	 * devether's attach (at runtime) */
+extern int bxe_attach(struct bxe_adapter *sc);
+	bxe_attach(ctlr);
+
 //	if (igbedetach(ctlr))
 //		return -1;
 
@@ -338,8 +347,10 @@
 			   pcidev->bus, pcidev->dev, pcidev->func);
 
 		/* Assuming MMIO */
-		mmio_paddr = pcidev->bar[0].mmio_base32 ? pcidev->bar[0].mmio_base32 :
-			pcidev->bar[0].mmio_base64;
+		/* Do this for each bar, based on whether it is mmio or not, and store
+		 * in the handles.  Move this to bxe_allocate_bars XME */
+		mmio_paddr = pci_get_membar(pcidev, 0);
+		assert(mmio_paddr);
 		mem = (void *)vmap_pmem_nocache(mmio_paddr, pcidev->bar[0].mmio_sz);
 		if (mem == NULL) {
 			printd("bxe: can't map %p\n", pcidev->bar[0].mmio_base32);
@@ -361,29 +372,38 @@
 			case 0x10:
 				break;
 		}
+
 		ctlr = kzmalloc(sizeof(struct bxe_adapter), 0);
 		if (ctlr == NULL) {
 			vunmap_vmem((uintptr_t) mem, pcidev->bar[0].mmio_sz);
 			error(Enomem);
 		}
+
+		/* TODO: Remove me */
+		ctlr->debug = 0xFFFFFFFF; /* flying monkeys     */
+
 		spinlock_init_irqsave(&ctlr->imlock);
 		spinlock_init_irqsave(&ctlr->tlock);
 		qlock_init(&ctlr->alock);
 		qlock_init(&ctlr->slock);
 		rendez_init(&ctlr->rrendez);
 
-		//ctlr->pci = pcidev;
+		ctlr->pcidev = pcidev;
 		ctlr->mmio = mem;
-		/* TODO: save 'mem' somewhere in the ctrl */
 		
 		if (bxereset(ctlr)) {
 			kfree(ctlr);
 			vunmap_vmem((uintptr_t) mem, pcidev->bar[0].mmio_sz);
 			continue;
 		}
+
+		/* this is done in bxe_attach too */ // XME
 		pci_set_bus_master(pcidev);
 
-		/* TODO Maybe ctlr add to list of devices */
+		/* BSD used mutexes for this list for other reasons */
+		qlock(&bxe_prev_mtx);
+		LIST_INSERT_HEAD(&bxe_prev_list, ctlr, node);
+		qunlock(&bxe_prev_mtx);
 	}
 }
 
@@ -393,39 +413,31 @@
 {
 	struct bxe_adapter *ctlr;
 
+	run_once(qlock_init(&bxe_prev_mtx));
 	/* Allocs ctlrs for all PCI devices matching our IDs, does various PCI and
 	 * MMIO/port setup */
 	run_once(bxepci());
 
-
-return -1;
-
-	/* Any adapter matches if no edev->port is supplied, otherwise the ports
-	 * must match. */
-	for (;;) {	// check all ctlrs
-		ctlr = (void*)0xdeadbeef;
-		/* only want inactive ones */
-		//if (ctlr->active)
-		//	continue;
-		// well, oop.s
-		/*
-		if (edev->port == 0 || edev->port == ctlr->port) {
-			ctlr->active = 1;
-			break;
-		}
-		*/
+	qlock(&bxe_prev_mtx);
+	LIST_FOREACH(ctlr, &bxe_prev_list, node) {
+		/* just take the first inactive ctlr on the list */
+		if (ctlr->active)
+			continue;
+		ctlr->active = 1;
+		break;
 	}
+	qunlock(&bxe_prev_mtx);
 	if (ctlr == NULL)
 		return -1;
 
 	edev->ctlr = ctlr;
-	//edev->port = ctlr->port;
-	//	edev->irq = ctlr->pci->irqline;
-	//edev->tbdf = MKBUS(BusPCI, ctlr->pci->bus, ctlr->pci->dev, ctlr->pci->func);
+	//edev->port = ctlr->port;	/* might just remove this from devether */
+	edev->irq = ctlr->pcidev->irqline;
+	edev->tbdf = MKBUS(BusPCI, ctlr->pcidev->bus, ctlr->pcidev->dev,
+	                   ctlr->pcidev->func);
 	edev->netif.mbps = 1000;
-	/* ea is the eth addr */
-	//memmove(edev->ea, ctlr->ra, Eaddrlen);
-
+	memmove(edev->ea, ctlr->link_params.mac_addr, Eaddrlen);
+	
 	/*
 	 * Linkage to the generic ethernet driver.
 	 */