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.
*/