From fba0315889f944a23c353aa7e979f21b59a2c741 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Wed, 8 Jun 2022 22:52:31 -0400 Subject: [PATCH] idualwifi7260 & iaxwifi200: Adaptations for FreeBSD/Haiku support. Mostly a few #ifdefs for the dmamem API, if_alloc, probe, and attach hooks. Basically the same changes in both drivers. The firmware name map is not really needed anymore; the OpenBSD drivers have unique firmware names and do not generally use ".ucode" extensions. So just use the filenames as-is and drop the map. --- .../kernel/drivers/network/wlan/Jamfile | 5 +- .../drivers/network/wlan/iaxwifi200/Jamfile | 22 +++ .../network/wlan/iaxwifi200/dev/pci/if_iwx.c | 185 ++++++++++++++++-- .../wlan/iaxwifi200/dev/pci/if_iwxvar.h | 6 + .../drivers/network/wlan/iaxwifi200/glue.c | 22 +++ .../network/wlan/idualwifi7260/Jamfile | 34 +--- .../wlan/idualwifi7260/dev/pci/if_iwm.c | 182 +++++++++++++++-- .../wlan/idualwifi7260/dev/pci/if_iwmvar.h | 7 +- .../drivers/network/wlan/idualwifi7260/glue.c | 54 +---- 9 files changed, 412 insertions(+), 105 deletions(-) create mode 100644 src/add-ons/kernel/drivers/network/wlan/iaxwifi200/Jamfile create mode 100644 src/add-ons/kernel/drivers/network/wlan/iaxwifi200/glue.c diff --git a/src/add-ons/kernel/drivers/network/wlan/Jamfile b/src/add-ons/kernel/drivers/network/wlan/Jamfile index 91e0cdac48..80b15b8041 100644 --- a/src/add-ons/kernel/drivers/network/wlan/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/Jamfile @@ -4,7 +4,6 @@ SubDir HAIKU_TOP src add-ons kernel drivers network wlan ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan aironetwifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan atheroswifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan broadcom43xx ; -SubInclude HAIKU_TOP src add-ons kernel drivers network wlan idualwifi7260 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2200 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi3945 ; @@ -13,3 +12,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network wlan marvell88w8335 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan marvell88w8363 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan ralinkwifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan realtekwifi ; + +# OpenBSD drivers +SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iaxwifi200 ; +SubInclude HAIKU_TOP src add-ons kernel drivers network wlan idualwifi7260 ; diff --git a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/Jamfile b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/Jamfile new file mode 100644 index 0000000000..cf5cc220db --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/Jamfile @@ -0,0 +1,22 @@ +SubDir HAIKU_TOP src add-ons kernel drivers network wlan iaxwifi200 ; + +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat openbsd_network compat ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat openbsd_wlan ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ; +UsePrivateHeaders net system ; +UsePrivateKernelHeaders ; + +SubDirCcFlags [ FDefines _KERNEL=1 _XOPEN_SOURCE ] + -Wno-unused -Wno-sign-compare ; + +UseHeaders [ FDirName $(SUBDIR) ] : true ; + +SEARCH_SOURCE += [ FDirName $(SUBDIR) dev pci ] ; + +KernelAddon iaxwifi200 : + if_iwx.c + glue.c + : + openbsd_wlan.a + libfreebsd_network.a + ; diff --git a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c index 9497ddbe2e..0aabc62579 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c +++ b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwx.c @@ -93,7 +93,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "bpfilter.h" +//#include "bpfilter.h" #include #include @@ -111,11 +111,11 @@ #include #include #include -#include +//#include #include #include -#include +//#include #if NBPFILTER > 0 #include @@ -123,6 +123,7 @@ #include #include #include +#include #include #include @@ -132,7 +133,17 @@ #include /* for SEQ_LT */ #undef DPRINTF /* defined in ieee80211_priv.h */ +#ifdef __FreeBSD_version +#include +#define DEVNAME(_s) "iwx" +#define SC_DEV_FOR_PCI sc->sc_dev +#define ifq_is_oactive(IFQ) ((if_getdrvflags(ifp) & IFF_DRV_OACTIVE) != 0) +#define ifq_set_oactive(IFQ) if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0) +#define ifq_clr_oactive(IFQ) if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE) +#define mallocarray(nmemb, size, type, flags) malloc((size) * (nmemb), (type), (flags)) +#else #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) +#endif #define IC2IFP(_ic_) (&(_ic_)->ic_if) @@ -507,7 +518,7 @@ int iwx_match(struct device *, void *, void *); int iwx_preinit(struct iwx_softc *); void iwx_attach_hook(struct device *); const struct iwx_device_cfg *iwx_find_device_cfg(struct iwx_softc *); -void iwx_attach(struct device *, struct device *, void *); +//void iwx_attach(struct device *, struct device *, void *); void iwx_init_task(void *); int iwx_activate(struct device *, int); void iwx_resume(struct iwx_softc *); @@ -1803,6 +1814,17 @@ iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma, dma->tag = tag; dma->size = size; +#ifdef __FreeBSD_version + err = bus_dmamap_create_obsd(tag, size, 1, size, 0, alignment, BUS_DMA_NOWAIT, + &dma->map, 1); + if (err) + goto fail; + + err = bus_dmamem_alloc(dma->map->_dmat, (void **)&dma->vaddr, + BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map->_dmamp); + if (err) + goto fail; +#else err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT, &dma->map); if (err) @@ -1812,7 +1834,9 @@ iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma, BUS_DMA_NOWAIT | BUS_DMA_ZERO); if (err) goto fail; +#endif +#ifndef __FreeBSD_version if (nsegs > 1) { err = ENOMEM; goto fail; @@ -1823,12 +1847,20 @@ iwx_dma_contig_alloc(bus_dma_tag_t tag, struct iwx_dma_info *dma, if (err) goto fail; dma->vaddr = va; +#endif err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL, BUS_DMA_NOWAIT); if (err) goto fail; +#ifdef __FreeBSD_version + if (dma->map->dm_nsegs > 1) { + err = ENOMEM; + goto fail; + } +#endif + bus_dmamap_sync(tag, dma->map, 0, size, BUS_DMASYNC_PREWRITE); dma->paddr = dma->map->dm_segs[0].ds_addr; @@ -1846,8 +1878,13 @@ iwx_dma_contig_free(struct iwx_dma_info *dma) bus_dmamap_sync(dma->tag, dma->map, 0, dma->size, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(dma->tag, dma->map); +#ifdef __FreeBSD_version + bus_dmamem_free(dma->tag, dma->vaddr, dma->map->_dmamp); + dma->map->_dmamp = NULL; +#else bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size); bus_dmamem_free(dma->tag, &dma->seg, 1); +#endif dma->vaddr = NULL; } bus_dmamap_destroy(dma->tag, dma->map); @@ -5635,7 +5672,11 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd *hcmd) err = EINVAL; goto out; } +#ifdef __FreeBSD_version + m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWX_RBUF_SIZE); +#else m = MCLGETL(NULL, M_DONTWAIT, totlen); +#endif if (m == NULL) { printf("%s: could not get fw cmd mbuf (%zd bytes)\n", DEVNAME(sc), totlen); @@ -6096,11 +6137,23 @@ iwx_tx(struct iwx_softc *sc, struct mbuf *m, struct ieee80211_node *ni) return err; } if (err) { +#ifdef __FreeBSD_version + /* Too many DMA segments, linearize mbuf. */ + struct mbuf* m1 = m_collapse(m, M_NOWAIT, IWX_TFH_NUM_TBS - 2); + if (m1 == NULL) { + device_printf(sc->sc_dev, + "%s: could not defrag mbuf\n", __func__); + m_freem(m); + return (ENOBUFS); + } + m = m1; +#else /* Too many DMA segments, linearize mbuf. */ if (m_defrag(m, M_DONTWAIT)) { m_freem(m); return ENOBUFS; } +#endif err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m, BUS_DMA_NOWAIT | BUS_DMA_WRITE); if (err) { @@ -9981,6 +10034,25 @@ iwx_intr_msix(void *arg) typedef void *iwx_match_t; static const struct pci_matchid iwx_devices[] = { +#ifdef __FreeBSD_version +#define PCI_VENDOR_INTEL 0x8086 +#define PCI_PRODUCT_INTEL_WL_22500_1 0x2723 /* Wi-Fi 6 AX200 */ +#define PCI_PRODUCT_INTEL_WL_22500_2 0x02f0 /* Wi-Fi 6 AX201 */ +#define PCI_PRODUCT_INTEL_WL_22500_3 0xa0f0 /* Wi-Fi 6 AX201 */ +#define PCI_PRODUCT_INTEL_WL_22500_4 0x34f0 /* Wi-Fi 6 AX201 */ +#define PCI_PRODUCT_INTEL_WL_22500_5 0x06f0 /* Wi-Fi 6 AX201 */ +#define PCI_PRODUCT_INTEL_WL_22500_6 0x43f0 /* Wi-Fi 6 AX201 */ +#define PCI_PRODUCT_INTEL_WL_22500_7 0x3df0 /* Wi-Fi 6 AX201 */ +#define PCI_PRODUCT_INTEL_WL_22500_8 0x4df0 /* Wi-Fi 6 AX201 */ +#define PCI_PRODUCT_INTEL_WL_22500_9 0x2725 /* Wi-Fi 6 AX210 */ +#define PCI_PRODUCT_INTEL_WL_22500_10 0x2726 /* Wi-Fi 6 AX211 */ +#define PCI_PRODUCT_INTEL_WL_22500_11 0x51f0 /* Wi-Fi 6 AX211 */ +#define PCI_PRODUCT_INTEL_WL_22500_12 0x7a70 /* Wi-Fi 6 AX211 */ +#define PCI_PRODUCT_INTEL_WL_22500_13 0x7af0 /* Wi-Fi 6 AX211 */ +#define PCI_PRODUCT_INTEL_WL_22500_14 0x7e40 /* Wi-Fi 6 AX210 */ +#define PCI_PRODUCT_INTEL_WL_22500_15 0x7f70 /* Wi-Fi 6 AX211 */ +#define PCI_PRODUCT_INTEL_WL_22500_16 0x54f0 /* Wi-Fi 6 AX211 */ +#endif { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_1 }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_2 }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_3 }, @@ -9999,13 +10071,29 @@ static const struct pci_matchid iwx_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_22500_16,}, }; +#ifdef __FreeBSD_version +static int +iwx_probe(device_t dev) +{ + int i; + for (i = 0; i < nitems(iwx_devices); i++) { + if (pci_get_vendor(dev) == iwx_devices[i].pm_vid && + pci_get_device(dev) == iwx_devices[i].pm_pid) { + return (BUS_PROBE_DEFAULT); + } + } + + return (ENXIO); +} +#else int iwx_match(struct device *parent, iwx_match_t match __unused, void *aux) { struct pci_attach_args *pa = aux; return pci_matchbyid(pa, iwx_devices, nitems(iwx_devices)); } +#endif /* * The device info table below contains device-specific config overrides. @@ -10380,9 +10468,11 @@ iwx_preinit(struct iwx_softc *sc) } if (sc->attached) { +#ifndef __FreeBSD_version /* Update MAC in case the upper layers changed it. */ IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr, ((struct arpcom *)ifp)->ac_enaddr); +#endif return 0; } @@ -10424,11 +10514,15 @@ iwx_preinit(struct iwx_softc *sc) /* Configure channel information obtained from firmware. */ ieee80211_channel_init(ifp); +#ifdef __HAIKU__ + IEEE80211_ADDR_COPY(IF_LLADDR(ifp), ic->ic_myaddr); +#else /* Configure MAC address. */ err = if_setlladdr(ifp, ic->ic_myaddr); if (err) printf("%s: could not set MAC address (error %d)\n", DEVNAME(sc), err); +#endif ieee80211_media_init(ifp, iwx_media_change, ieee80211_media_status); @@ -10516,11 +10610,21 @@ iwx_find_device_cfg(struct iwx_softc *sc) } +#ifdef __FreeBSD_version +static int +iwx_attach(device_t dev) +#else void iwx_attach(struct device *parent, struct device *self, void *aux) +#endif { +#ifdef __FreeBSD_version +#define pa dev + struct iwx_softc *sc = device_get_softc(dev); +#else struct iwx_softc *sc = (void *)self; struct pci_attach_args *pa = aux; +#endif pci_intr_handle_t ih; pcireg_t reg, memtype; struct ieee80211com *ic = &sc->sc_ic; @@ -10531,10 +10635,22 @@ iwx_attach(struct device *parent, struct device *self, void *aux) int txq_i, i, j; size_t ctxt_info_size; +#ifdef __FreeBSD_version + sc->sc_dev = dev; + sc->sc_pid = pci_get_device(dev); + sc->sc_dmat = bus_get_dma_tag(sc->sc_dev); + bus_dma_tag_create(sc->sc_dmat, 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, + &sc->sc_dmat); + + if_alloc_inplace(ifp, IFT_ETHER); +#else sc->sc_pid = PCI_PRODUCT(pa->pa_id); sc->sc_pct = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; sc->sc_dmat = pa->pa_dmat; +#endif rw_init(&sc->ioctl_rwl, "iwxioctl"); @@ -10543,7 +10659,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux) if (err == 0) { printf("%s: PCIe capability structure not found!\n", DEVNAME(sc)); - return; + return -1; } /* @@ -10558,15 +10674,19 @@ iwx_attach(struct device *parent, struct device *self, void *aux) &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz, 0); if (err) { printf("%s: can't map mem space\n", DEVNAME(sc)); - return; + return -1; } if (pci_intr_map_msix(pa, 0, &ih) == 0) { sc->sc_msix = 1; } else if (pci_intr_map_msi(pa, &ih)) { +#ifndef __HAIKU__ if (pci_intr_map(pa, &ih)) { +#else + { +#endif printf("%s: can't map interrupt\n", DEVNAME(sc)); - return; + return -1; } /* Hardware bug workaround. */ reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, @@ -10591,7 +10711,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux) if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); - return; + return -1; } printf(", %s\n", intrstr); @@ -10612,6 +10732,10 @@ iwx_attach(struct device *parent, struct device *self, void *aux) sc->sc_hw_rev = (sc->sc_hw_rev & 0xfff0) | (IWX_CSR_HW_REV_STEP(sc->sc_hw_rev << 2) << 2); +#ifdef __FreeBSD_version +#undef PCI_PRODUCT +#define PCI_PRODUCT(pa) pci_get_device(dev) +#endif switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_INTEL_WL_22500_1: sc->sc_fwname = IWX_CC_A_FW; @@ -10628,7 +10752,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux) /* These devices should be QuZ only. */ if (sc->sc_hw_rev != IWX_CSR_HW_REV_TYPE_QUZ) { printf("%s: unsupported AX201 adapter\n", DEVNAME(sc)); - return; + return -1; } sc->sc_fwname = IWX_QUZ_A_HR_B_FW; sc->sc_device_family = IWX_DEVICE_FAMILY_22000; @@ -10706,8 +10830,11 @@ iwx_attach(struct device *parent, struct device *self, void *aux) break; default: printf("%s: unknown adapter type\n", DEVNAME(sc)); - return; + return -1; } +#ifdef __FreeBSD_version +#undef PCI_PRODUCT +#endif cfg = iwx_find_device_cfg(sc); if (cfg) { @@ -10739,7 +10866,7 @@ iwx_attach(struct device *parent, struct device *self, void *aux) if (err) { printf("%s: could not allocate memory for loading firmware\n", DEVNAME(sc)); - return; + return -1; } if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { @@ -10894,13 +11021,20 @@ iwx_attach(struct device *parent, struct device *self, void *aux) ic->ic_ampdu_rx_stop = iwx_ampdu_rx_stop; ic->ic_ampdu_tx_start = iwx_ampdu_tx_start; ic->ic_ampdu_tx_stop = NULL; + +#ifdef __HAIKU__ + mtx_lock(&Giant); + iwx_preinit(sc); + mtx_unlock(&Giant); +#else /* * We cannot read the MAC address without loading the * firmware from disk. Postpone until mountroot is done. */ config_mountroot(self, iwx_attach_hook); +#endif - return; + return 0; fail4: while (--txq_i >= 0) iwx_free_tx_ring(sc, &sc->txq[txq_i]); @@ -10911,7 +11045,7 @@ fail4: while (--txq_i >= 0) fail1: iwx_dma_contig_free(&sc->ctxt_info_dma); iwx_dma_contig_free(&sc->prph_scratch_dma); iwx_dma_contig_free(&sc->prph_info_dma); - return; + return -1; } #if NBPFILTER > 0 @@ -11011,6 +11145,30 @@ iwx_wakeup(struct iwx_softc *sc) return 0; } +#ifdef __FreeBSD_version +static device_method_t iwx_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, iwx_probe), + DEVMETHOD(device_attach, iwx_attach), +#if 0 + DEVMETHOD(device_detach, iwx_detach), + DEVMETHOD(device_suspend, iwx_suspend), + DEVMETHOD(device_resume, iwx_resume), +#endif + + DEVMETHOD_END +}; + +static driver_t iwx_pci_driver = { + "iwx", + iwx_pci_methods, + sizeof (struct iwx_softc) +}; + +static devclass_t iwx_devclass; + +DRIVER_MODULE(iwx, pci, iwx_pci_driver, iwx_devclass, NULL, NULL); +#else int iwx_activate(struct device *self, int act) { @@ -11050,3 +11208,4 @@ const struct cfattach iwx_ca = { sizeof(struct iwx_softc), iwx_match, iwx_attach, NULL, iwx_activate }; +#endif diff --git a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxvar.h b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxvar.h index 6468bfec46..d754ad755f 100644 --- a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxvar.h +++ b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/dev/pci/if_iwxvar.h @@ -612,7 +612,11 @@ const struct iwx_device_cfg iwx_2ax_cfg_so_jf_b0 = { #define IWX_SUBDEVICE_CORES(subdevice) ((uint16_t)((subdevice) & 0x1c00) >> 10) struct iwx_softc { +#ifdef __FreeBSD_version + device_t sc_dev; +#else struct device sc_dev; +#endif struct ieee80211com sc_ic; int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); int sc_newstate_pending; @@ -654,8 +658,10 @@ struct iwx_softc { bus_size_t sc_sz; bus_dma_tag_t sc_dmat; pci_product_id_t sc_pid; +#ifndef __FreeBSD_version pci_chipset_tag_t sc_pct; pcitag_t sc_pcitag; +#endif const void *sc_ih; int sc_msix; diff --git a/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/glue.c b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/glue.c new file mode 100644 index 0000000000..609752bc98 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/wlan/iaxwifi200/glue.c @@ -0,0 +1,22 @@ +/* + * Copyright 2022, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ + +#include + + +HAIKU_FBSD_WLAN_DRIVER_GLUE(iaxwifi200, iwx, pci) +NO_HAIKU_FBSD_MII_DRIVER(); +NO_HAIKU_REENABLE_INTERRUPTS(); +HAIKU_DRIVER_REQUIREMENTS(OBSD_WLAN); +HAIKU_FIRMWARE_VERSION(0); +NO_HAIKU_FIRMWARE_NAME_MAP(); + + +int +HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) +{ + // We only support MSI(-X), so we handle all interrupts. + return 1; +} diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile index 876bc25e2a..9de5fd0bcb 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/Jamfile @@ -1,42 +1,22 @@ SubDir HAIKU_TOP src add-ons kernel drivers network wlan idualwifi7260 ; -UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] - : true ; -UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat openbsd_network compat ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat openbsd_wlan ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ; UsePrivateHeaders net system ; UsePrivateKernelHeaders ; -SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 _XOPEN_SOURCE ] - -Wno-format - -Wno-unused - -Wno-uninitialized ; +SubDirCcFlags [ FDefines _KERNEL=1 _XOPEN_SOURCE ] + -Wno-unused -Wno-sign-compare ; UseHeaders [ FDirName $(SUBDIR) ] : true ; -SEARCH_SOURCE += [ FDirName $(SUBDIR) dev iwm ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) dev pci ] ; KernelAddon idualwifi7260 : - if_iwm_7000.c - if_iwm_8000.c - if_iwm_9000.c - if_iwm_9260.c - if_iwm_binding.c - if_iwm_fw.c - if_iwm_led.c - if_iwm_mac_ctxt.c - if_iwm_notif_wait.c - if_iwm_pcie_trans.c - if_iwm_phy_ctxt.c - if_iwm_phy_db.c - if_iwm_power.c - if_iwm_scan.c - if_iwm_sf.c - if_iwm_sta.c - if_iwm_time_event.c - if_iwm_util.c if_iwm.c glue.c : - freebsd_wlan.a + openbsd_wlan.a libfreebsd_network.a ; diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c index 6de80bd303..1473f497e1 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwm.c @@ -106,7 +106,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include "bpfilter.h" +//#include "bpfilter.h" #include #include @@ -124,11 +124,11 @@ #include #include #include -#include +//#include #include #include -#include +//#include #if NBPFILTER > 0 #include @@ -136,6 +136,7 @@ #include #include #include +#include #include #include @@ -148,7 +149,16 @@ #include /* for SEQ_LT */ #undef DPRINTF /* defined in ieee80211_priv.h */ +#ifdef __FreeBSD_version +#include +#define DEVNAME(_s) "iwm" +#define SC_DEV_FOR_PCI sc->sc_dev +#define ifq_is_oactive(IFQ) ((if_getdrvflags(ifp) & IFF_DRV_OACTIVE) != 0) +#define ifq_set_oactive(IFQ) if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0) +#define ifq_clr_oactive(IFQ) if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE) +#else #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) +#endif #define IC2IFP(_ic_) (&(_ic_)->ic_if) @@ -558,7 +568,7 @@ int iwm_intr_msix(void *); int iwm_match(struct device *, void *, void *); int iwm_preinit(struct iwm_softc *); void iwm_attach_hook(struct device *); -void iwm_attach(struct device *, struct device *, void *); +//void iwm_attach(struct device *, struct device *, void *); void iwm_init_task(void *); int iwm_activate(struct device *, int); void iwm_resume(struct iwm_softc *); @@ -1217,6 +1227,17 @@ iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma, dma->tag = tag; dma->size = size; +#ifdef __FreeBSD_version + err = bus_dmamap_create_obsd(tag, size, 1, size, 0, alignment, BUS_DMA_NOWAIT, + &dma->map, 1); + if (err) + goto fail; + + err = bus_dmamem_alloc(dma->map->_dmat, (void **)&dma->vaddr, + BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &dma->map->_dmamp); + if (err) + goto fail; +#else err = bus_dmamap_create(tag, size, 1, size, 0, BUS_DMA_NOWAIT, &dma->map); if (err) @@ -1232,6 +1253,7 @@ iwm_dma_contig_alloc(bus_dma_tag_t tag, struct iwm_dma_info *dma, if (err) goto fail; dma->vaddr = va; +#endif err = bus_dmamap_load(tag, dma->map, dma->vaddr, size, NULL, BUS_DMA_NOWAIT); @@ -1256,8 +1278,13 @@ iwm_dma_contig_free(struct iwm_dma_info *dma) bus_dmamap_sync(dma->tag, dma->map, 0, dma->size, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(dma->tag, dma->map); +#ifdef __FreeBSD_version + bus_dmamem_free(dma->tag, dma->vaddr, dma->map->_dmamp); + dma->map->_dmamp = NULL; +#else bus_dmamem_unmap(dma->tag, dma->vaddr, dma->size); bus_dmamem_free(dma->tag, &dma->seg, 1); +#endif dma->vaddr = NULL; } bus_dmamap_destroy(dma->tag, dma->map); @@ -6315,7 +6342,11 @@ iwm_send_cmd(struct iwm_softc *sc, struct iwm_host_cmd *hcmd) err = EINVAL; goto out; } +#ifdef __FreeBSD_version + m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, IWM_RBUF_SIZE); +#else m = MCLGETL(NULL, M_DONTWAIT, totlen); +#endif if (m == NULL) { printf("%s: could not get fw cmd mbuf (%zd bytes)\n", DEVNAME(sc), totlen); @@ -6906,11 +6937,23 @@ iwm_tx(struct iwm_softc *sc, struct mbuf *m, struct ieee80211_node *ni, int ac) return err; } if (err) { +#ifdef __FreeBSD_version + /* Too many DMA segments, linearize mbuf. */ + struct mbuf* m1 = m_collapse(m, M_NOWAIT, IWM_NUM_OF_TBS - 2); + if (m1 == NULL) { + device_printf(sc->sc_dev, + "%s: could not defrag mbuf\n", __func__); + m_freem(m); + return (ENOBUFS); + } + m = m1; +#else /* Too many DMA segments, linearize mbuf. */ if (m_defrag(m, M_DONTWAIT)) { m_freem(m); return ENOBUFS; } +#endif err = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m, BUS_DMA_NOWAIT | BUS_DMA_WRITE); if (err) { @@ -11534,6 +11577,25 @@ iwm_intr_msix(void *arg) typedef void *iwm_match_t; static const struct pci_matchid iwm_devices[] = { +#ifdef __FreeBSD_version +#define PCI_VENDOR_INTEL 0x8086 +#define PCI_PRODUCT_INTEL_WL_3160_1 0x08b3 +#define PCI_PRODUCT_INTEL_WL_3160_2 0x08b4 +#define PCI_PRODUCT_INTEL_WL_3165_1 0x3165 +#define PCI_PRODUCT_INTEL_WL_3165_2 0x3166 +#define PCI_PRODUCT_INTEL_WL_3168_1 0x24fb +#define PCI_PRODUCT_INTEL_WL_7260_1 0x08b1 +#define PCI_PRODUCT_INTEL_WL_7260_2 0x08b2 +#define PCI_PRODUCT_INTEL_WL_7265_1 0x095a +#define PCI_PRODUCT_INTEL_WL_7265_2 0x095b +#define PCI_PRODUCT_INTEL_WL_8260_1 0x24f3 +#define PCI_PRODUCT_INTEL_WL_8260_2 0x24f4 +#define PCI_PRODUCT_INTEL_WL_8265_1 0x24fd +#define PCI_PRODUCT_INTEL_WL_9560_1 0x9df0 +#define PCI_PRODUCT_INTEL_WL_9560_2 0xa370 +#define PCI_PRODUCT_INTEL_WL_9560_3 0x31dc +#define PCI_PRODUCT_INTEL_WL_9260_1 0x2526 +#endif { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_3160_1 }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_3160_2 }, { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_3165_1 }, @@ -11552,12 +11614,29 @@ static const struct pci_matchid iwm_devices[] = { { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_WL_9560_3 }, }; +#ifdef __FreeBSD_version +static int +iwm_probe(device_t dev) +{ + int i; + + for (i = 0; i < nitems(iwm_devices); i++) { + if (pci_get_vendor(dev) == iwm_devices[i].pm_vid && + pci_get_device(dev) == iwm_devices[i].pm_pid) { + return (BUS_PROBE_DEFAULT); + } + } + + return (ENXIO); +} +#else int iwm_match(struct device *parent, iwm_match_t match __unused, void *aux) { return pci_matchbyid((struct pci_attach_args *)aux, iwm_devices, nitems(iwm_devices)); } +#endif int iwm_preinit(struct iwm_softc *sc) @@ -11573,9 +11652,11 @@ iwm_preinit(struct iwm_softc *sc) } if (sc->attached) { +#ifndef __FreeBSD_version /* Update MAC in case the upper layers changed it. */ IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr, ((struct arpcom *)ifp)->ac_enaddr); +#endif return 0; } @@ -11607,11 +11688,15 @@ iwm_preinit(struct iwm_softc *sc) /* Configure channel information obtained from firmware. */ ieee80211_channel_init(ifp); +#ifdef __HAIKU__ + IEEE80211_ADDR_COPY(IF_LLADDR(ifp), ic->ic_myaddr); +#else /* Configure MAC address. */ err = if_setlladdr(ifp, ic->ic_myaddr); if (err) printf("%s: could not set MAC address (error %d)\n", DEVNAME(sc), err); +#endif ieee80211_media_init(ifp, iwm_media_change, ieee80211_media_status); @@ -11628,11 +11713,21 @@ iwm_attach_hook(struct device *self) iwm_preinit(sc); } +#ifdef __FreeBSD_version +static int +iwm_attach(device_t dev) +#else void iwm_attach(struct device *parent, struct device *self, void *aux) +#endif { +#ifdef __FreeBSD_version +#define pa dev + struct iwm_softc *sc = device_get_softc(dev); +#else struct iwm_softc *sc = (void *)self; struct pci_attach_args *pa = aux; +#endif pci_intr_handle_t ih; pcireg_t reg, memtype; struct ieee80211com *ic = &sc->sc_ic; @@ -11641,9 +11736,20 @@ iwm_attach(struct device *parent, struct device *self, void *aux) int err; int txq_i, i, j; +#ifdef __FreeBSD_version + sc->sc_dev = dev; + sc->sc_dmat = bus_get_dma_tag(sc->sc_dev); + bus_dma_tag_create(sc->sc_dmat, 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + BUS_SPACE_MAXSIZE_32BIT, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, + &sc->sc_dmat); + + if_alloc_inplace(ifp, IFT_ETHER); +#else sc->sc_pct = pa->pa_pc; sc->sc_pcitag = pa->pa_tag; sc->sc_dmat = pa->pa_dmat; +#endif rw_init(&sc->ioctl_rwl, "iwmioctl"); @@ -11652,7 +11758,7 @@ iwm_attach(struct device *parent, struct device *self, void *aux) if (err == 0) { printf("%s: PCIe capability structure not found!\n", DEVNAME(sc)); - return; + goto fail; } /* @@ -11667,15 +11773,19 @@ iwm_attach(struct device *parent, struct device *self, void *aux) &sc->sc_st, &sc->sc_sh, NULL, &sc->sc_sz, 0); if (err) { printf("%s: can't map mem space\n", DEVNAME(sc)); - return; + goto fail; } if (pci_intr_map_msix(pa, 0, &ih) == 0) { sc->sc_msix = 1; } else if (pci_intr_map_msi(pa, &ih)) { +#ifndef __HAIKU__ if (pci_intr_map(pa, &ih)) { +#else + { +#endif printf("%s: can't map interrupt\n", DEVNAME(sc)); - return; + goto fail; } /* Hardware bug workaround. */ reg = pci_conf_read(sc->sc_pct, sc->sc_pcitag, @@ -11700,11 +11810,15 @@ iwm_attach(struct device *parent, struct device *self, void *aux) if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); - return; + goto fail; } printf(", %s\n", intrstr); sc->sc_hw_rev = IWM_READ(sc, IWM_CSR_HW_REV); +#ifdef __FreeBSD_version +#undef PCI_PRODUCT +#define PCI_PRODUCT(pa) pci_get_device(dev) +#endif switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_INTEL_WL_3160_1: case PCI_PRODUCT_INTEL_WL_3160_2: @@ -11793,8 +11907,11 @@ iwm_attach(struct device *parent, struct device *self, void *aux) break; default: printf("%s: unknown adapter type\n", DEVNAME(sc)); - return; + goto fail; } +#ifdef __FreeBSD_version +#undef PCI_PRODUCT +#endif /* * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have @@ -11811,7 +11928,7 @@ iwm_attach(struct device *parent, struct device *self, void *aux) if (iwm_prepare_card_hw(sc) != 0) { printf("%s: could not initialize hardware\n", DEVNAME(sc)); - return; + goto fail; } /* @@ -11828,7 +11945,7 @@ iwm_attach(struct device *parent, struct device *self, void *aux) 25000); if (!err) { printf("%s: Failed to wake up the nic\n", DEVNAME(sc)); - return; + goto fail; } if (iwm_nic_lock(sc)) { @@ -11843,7 +11960,7 @@ iwm_attach(struct device *parent, struct device *self, void *aux) iwm_nic_unlock(sc); } else { printf("%s: Failed to lock the nic\n", DEVNAME(sc)); - return; + goto fail; } } @@ -11856,7 +11973,7 @@ iwm_attach(struct device *parent, struct device *self, void *aux) if (err) { printf("%s: could not allocate memory for firmware\n", DEVNAME(sc)); - return; + goto fail; } /* Allocate "Keep Warm" page, used internally by the card. */ @@ -12006,13 +12123,19 @@ iwm_attach(struct device *parent, struct device *self, void *aux) ic->ic_ampdu_rx_stop = iwm_ampdu_rx_stop; ic->ic_ampdu_tx_start = iwm_ampdu_tx_start; ic->ic_ampdu_tx_stop = iwm_ampdu_tx_stop; +#ifdef __HAIKU__ + mtx_lock(&Giant); + iwm_preinit(sc); + mtx_unlock(&Giant); +#else /* * We cannot read the MAC address without loading the * firmware from disk. Postpone until mountroot is done. */ config_mountroot(self, iwm_attach_hook); +#endif - return; + return 0; fail4: while (--txq_i >= 0) iwm_free_tx_ring(sc, &sc->txq[txq_i]); @@ -12023,7 +12146,11 @@ fail3: if (sc->ict_dma.vaddr != NULL) fail2: iwm_dma_contig_free(&sc->kw_dma); fail1: iwm_dma_contig_free(&sc->fw_dma); - return; +#ifdef __HAIKU__ +fail: + if_free_inplace(ifp); +#endif + return -1; } #if NBPFILTER > 0 @@ -12123,6 +12250,30 @@ iwm_wakeup(struct iwm_softc *sc) return 0; } +#ifdef __FreeBSD_version +static device_method_t iwm_pci_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, iwm_probe), + DEVMETHOD(device_attach, iwm_attach), +#if 0 + DEVMETHOD(device_detach, iwm_detach), + DEVMETHOD(device_suspend, iwm_suspend), + DEVMETHOD(device_resume, iwm_resume), +#endif + + DEVMETHOD_END +}; + +static driver_t iwm_pci_driver = { + "iwm", + iwm_pci_methods, + sizeof (struct iwm_softc) +}; + +static devclass_t iwm_devclass; + +DRIVER_MODULE(iwm, pci, iwm_pci_driver, iwm_devclass, NULL, NULL); +#else int iwm_activate(struct device *self, int act) { @@ -12162,3 +12313,4 @@ const struct cfattach iwm_ca = { sizeof(struct iwm_softc), iwm_match, iwm_attach, NULL, iwm_activate }; +#endif diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwmvar.h b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwmvar.h index ec19f5462f..ca3eb050b7 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwmvar.h +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/dev/pci/if_iwmvar.h @@ -295,7 +295,6 @@ struct iwm_rx_ring { struct iwm_dma_info free_desc_dma; struct iwm_dma_info stat_dma; struct iwm_dma_info used_desc_dma; - struct iwm_dma_info buf_dma; void *desc; struct iwm_rb_status *stat; struct iwm_rx_data data[IWM_RX_MQ_RING_COUNT]; @@ -472,7 +471,11 @@ struct iwm_ba_task_data { }; struct iwm_softc { +#ifdef __FreeBSD_version + device_t sc_dev; +#else struct device sc_dev; +#endif struct ieee80211com sc_ic; int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); int sc_newstate_pending; @@ -503,8 +506,10 @@ struct iwm_softc { bus_space_handle_t sc_sh; bus_size_t sc_sz; bus_dma_tag_t sc_dmat; +#ifndef __FreeBSD_version pci_chipset_tag_t sc_pct; pcitag_t sc_pcitag; +#endif const void *sc_ih; int sc_msix; diff --git a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/glue.c b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/glue.c index 258f226c5b..2abece07dd 100644 --- a/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/glue.c +++ b/src/add-ons/kernel/drivers/network/wlan/idualwifi7260/glue.c @@ -1,64 +1,22 @@ /* - * Copyright 2018, Haiku, Inc. All rights reserved. - * Distributed under the terms of the MIT license. + * Copyright 2022, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. */ - -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -#include -#include +#include HAIKU_FBSD_WLAN_DRIVER_GLUE(idualwifi7260, iwm, pci) NO_HAIKU_FBSD_MII_DRIVER(); NO_HAIKU_REENABLE_INTERRUPTS(); -HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_WLAN); +HAIKU_DRIVER_REQUIREMENTS(OBSD_WLAN); HAIKU_FIRMWARE_VERSION(1); -HAIKU_FIRMWARE_NAME_MAP({ - {"iwm3160fw", "iwm-3160-17.ucode"}, - {"iwm3168fw", "iwm-3168-22.ucode"}, - {"iwm7260fw", "iwm-7260-17.ucode"}, - {"iwm7265fw", "iwm-7265-17.ucode"}, - {"iwm7265Dfw", "iwm-7265D-22.ucode"}, - {"iwm8000Cfw", "iwm-8000C-22.ucode"}, - {"iwm8265fw", "iwm-8265-22.ucode"}, - {"iwm9000fw", "iwm-9000-34.ucode"}, - {"iwm9260fw", "iwm-9260-34.ucode"}, -}); +NO_HAIKU_FIRMWARE_NAME_MAP(); int HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) { - struct iwm_softc* sc = (struct iwm_softc*)device_get_softc(dev); - uint32 r1, r2; - - r1 = IWM_READ(sc, IWM_CSR_INT); - /* "hardware gone" (where, fishing?) */ - if (r1 == 0xffffffff || (r1 & 0xfffffff0) == 0xa5a5a5a0) - return 0; - r2 = IWM_READ(sc, IWM_CSR_FH_INT_STATUS); - - if (r1 == 0 && r2 == 0) - return 0; // not for us - - atomic_set((int32*)&sc->sc_intr_status_1, r1); - atomic_set((int32*)&sc->sc_intr_status_2, r2); - - IWM_WRITE(sc, IWM_CSR_INT_MASK, 0); - // disable interrupts - + // We only support MSI(-X), so we handle all interrupts. return 1; }