BXE: attach
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 23 Jan 2015 22:02:00 +0000 (17:02 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 3 Feb 2015 15:12:30 +0000 (10:12 -0500)
Attaches in the reset/pnp (at boot time).

There's still a lot of obvious stuff that's not hooked up.  Grep XME.

kern/drivers/net/bxe/bxe.c
kern/drivers/net/bxe/bxe.h
kern/drivers/net/bxe/bxe_dev.c

index c9f9303..3f70e45 100644 (file)
@@ -251,6 +251,7 @@ static device_method_t bxe_methods[] = {
 
 #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 @@ bxe_ioctl(if_t ifp,
         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 @@ bxe_interrupt_free(struct bxe_adapter *sc)
 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 @@ bxe_interrupt_alloc(struct bxe_adapter *sc)
 
     return (rc);
 #endif
-    return -1;
 }
 
 static void
@@ -13298,7 +13300,6 @@ bxe_allocate_bars(struct bxe_adapter *sc)
 {
     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 @@ bxe_allocate_bars(struct bxe_adapter *sc)
         /* 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 @@ bxe_allocate_bars(struct bxe_adapter *sc)
               (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 @@ bxe_is_pcie_pending(struct bxe_adapter *sc)
 static void
 bxe_probe_pci_caps(struct bxe_adapter *sc)
 {
+               // XXX XME 
 #if 0
     uint16_t link_status;
     int reg;
@@ -13989,6 +14016,7 @@ bxe_get_shmem_info(struct bxe_adapter *sc)
         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 @@ bxe_get_shmem_info(struct bxe_adapter *sc)
     return (0);
 }
 
+// TODO XME XME
 static void
 bxe_get_tunable_params(struct bxe_adapter *sc)
 {
@@ -14115,49 +14144,46 @@ bxe_get_tunable_params(struct bxe_adapter *sc)
 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 @@ bxe_get_device_info(struct bxe_adapter *sc)
         (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_device_info(struct bxe_adapter *sc)
     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 @@ bxe_alloc_hsi_mem(struct bxe_adapter *sc)
                             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 @@ bxe_prev_unload_uncommon(struct bxe_adapter *sc)
     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 @@ bxe_add_sysctls(struct bxe_adapter *sc)
         }
     }
 }
+#endif
 
 /*
  * Device attach function.
@@ -16204,28 +16238,25 @@ bxe_add_sysctls(struct bxe_adapter *sc)
  * 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 @@ bxe_attach(struct bxe_adapter *sc)
     /* 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_attach(struct bxe_adapter *sc)
     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 @@ bxe_attach(struct bxe_adapter *sc)
     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 @@ bxe_detach(struct pcidev *dev)
     if (ifp != NULL) {
         ether_ifdetach(ifp);
     }
-    ifmedia_removeall(&sc->ifmedia);
+    ifmedia_removeall(&sc->media);
 
     /* XXX do the following based on driver state... */
 
index 4b786a1..b89e58b 100644 (file)
@@ -62,6 +62,8 @@ typedef uint64_t uintmax_t;
 #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 @@ struct bxe_device_type
 #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 @@ struct bxe_bar {
     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 @@ struct bxe_devinfo {
      *   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 @@ struct bxe_adapter {
         * 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 @@ void bxe_reg_write32(struct bxe_adapter *sc, bus_size_t offset, uint32_t val);
 #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 @@ void bxe_dump_mbuf_data(struct bxe_adapter *sc, char *pTag,
 
 /* 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 */
index 11e87ed..da0fbb0 100644 (file)
@@ -258,6 +258,10 @@ static void bxeattach(struct ether *edev)
 
        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 @@ static int bxereset(struct bxe_adapter *ctlr)
 {
        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 @@ static void bxepci(void)
                           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 @@ static void bxepci(void)
                        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 @@ static int bxepnp(struct ether *edev)
 {
        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.
         */