From 28ca18780111bd42b373a8b7a016b0b64fa13087 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 17 Jul 2018 19:46:44 -0400 Subject: [PATCH] ralinkwifi: Sync with FreeBSD 11.1. Untested, but the changes are mostly adapations to the new KPIs. --- .../kernel/drivers/network/wlan/Jamfile | 2 +- .../drivers/network/wlan/ralinkwifi/Jamfile | 14 +- .../wlan/ralinkwifi/dev/ral/if_ral_pci.c | 6 +- .../network/wlan/ralinkwifi/dev/ral/rt2560.c | 436 +++++----- .../wlan/ralinkwifi/dev/ral/rt2560reg.h | 4 +- .../wlan/ralinkwifi/dev/ral/rt2560var.h | 16 +- .../network/wlan/ralinkwifi/dev/ral/rt2661.c | 404 ++++----- .../wlan/ralinkwifi/dev/ral/rt2661reg.h | 4 +- .../wlan/ralinkwifi/dev/ral/rt2661var.h | 15 +- .../network/wlan/ralinkwifi/dev/ral/rt2860.c | 809 +++++++++++------- .../wlan/ralinkwifi/dev/ral/rt2860reg.h | 281 ++++-- .../wlan/ralinkwifi/dev/ral/rt2860var.h | 17 +- .../drivers/network/wlan/ralinkwifi/glue.c | 15 +- 13 files changed, 1136 insertions(+), 887 deletions(-) diff --git a/src/add-ons/kernel/drivers/network/wlan/Jamfile b/src/add-ons/kernel/drivers/network/wlan/Jamfile index 0a1233a7b4..30ca1a8f08 100644 --- a/src/add-ons/kernel/drivers/network/wlan/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/Jamfile @@ -6,7 +6,6 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network wlan marvell88w8335 ; # FreeBSD 9.3 drivers SubInclude HAIKU_TOP src add-ons kernel drivers network wlan broadcom43xx ; 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 wavelanwifi ; # FreeBSD 11.1 drivers @@ -15,6 +14,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network wlan atheroswifi ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi2100 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi3945 ; SubInclude HAIKU_TOP src add-ons kernel drivers network wlan iprowifi4965 ; +SubInclude HAIKU_TOP src add-ons kernel drivers network wlan ralinkwifi ; # FreeBSD 11.2 drivers SubInclude HAIKU_TOP src add-ons kernel drivers network wlan idualwifi7260 ; diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile index ccdfb5b976..7211af2995 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/Jamfile @@ -1,14 +1,14 @@ SubDir HAIKU_TOP src add-ons kernel drivers network wlan ralinkwifi ; -UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ] : true ; -UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_wlan ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_wlan ] : true ; UsePrivateHeaders net system ; UsePrivateKernelHeaders ; -SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] - -Wno-format - -Wno-unused +SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] + -Wno-format + -Wno-unused -Wno-uninitialized ; UseHeaders [ FDirName $(SUBDIR) ] : true ; @@ -22,8 +22,8 @@ KernelAddon ralinkwifi : rt2860.c glue.c : - libfreebsd_wlan.a - libfreebsd_network.a + libfreebsd11_wlan.a + libfreebsd11_network.a ; HAIKU_WIFI_FIRMWARE_PACKAGES on ralinkwifi = RT61_Firmware_V1.2 diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c index d3a269210a..4b2dd35191 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/if_ral_pci.c @@ -16,7 +16,7 @@ */ #include -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: releng/11.1/sys/dev/ral/if_ral_pci.c 287197 2015-08-27 08:56:39Z glebius $"); /* * PCI/Cardbus front-end for the Ralink RT2560/RT2561/RT2561S/RT2661 driver. @@ -28,6 +28,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -93,7 +94,10 @@ static const struct ral_pci_ident ral_pci_ids[] = { { 0x1814, 0x3562, "Ralink Technology RT3562" }, { 0x1814, 0x3592, "Ralink Technology RT3592" }, { 0x1814, 0x3593, "Ralink Technology RT3593" }, + { 0x1814, 0x5360, "Ralink Technology RT5390" }, + { 0x1814, 0x5362, "Ralink Technology RT5392" }, { 0x1814, 0x5390, "Ralink Technology RT5390" }, + { 0x1814, 0x5392, "Ralink Technology RT5392" }, { 0x1814, 0x539a, "Ralink Technology RT5390" }, { 0x1814, 0x539f, "Ralink Technology RT5390" }, { 0x1a3b, 0x1059, "AWT RT2890" }, diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c index 0c3a00361f..bf512b347a 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560.c @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ral/rt2560.c 300752 2016-05-26 16:05:19Z avos $ */ /*- * Copyright (c) 2005, 2006 @@ -18,7 +18,7 @@ */ #include -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: releng/11.1/sys/dev/ral/rt2560.c 300752 2016-05-26 16:05:19Z avos $"); /*- * Ralink Technology RT2560 chipset driver @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -116,6 +117,8 @@ static void rt2560_beacon_expire(struct rt2560_softc *); static void rt2560_wakeup_expire(struct rt2560_softc *); static void rt2560_scan_start(struct ieee80211com *); static void rt2560_scan_end(struct ieee80211com *); +static void rt2560_getradiocaps(struct ieee80211com *, int, int *, + struct ieee80211_channel[]); static void rt2560_set_channel(struct ieee80211com *); static void rt2560_setup_tx_desc(struct rt2560_softc *, struct rt2560_tx_desc *, uint32_t, int, int, int, @@ -126,10 +129,10 @@ static int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); static int rt2560_tx_data(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); -static void rt2560_start_locked(struct ifnet *); -static void rt2560_start(struct ifnet *); +static int rt2560_transmit(struct ieee80211com *, struct mbuf *); +static void rt2560_start(struct rt2560_softc *); static void rt2560_watchdog(void *); -static int rt2560_ioctl(struct ifnet *, u_long, caddr_t); +static void rt2560_parent(struct ieee80211com *); static void rt2560_bbp_write(struct rt2560_softc *, uint8_t, uint8_t); static uint8_t rt2560_bbp_read(struct rt2560_softc *, uint8_t); @@ -143,14 +146,15 @@ static void rt2560_disable_rf_tune(struct rt2560_softc *); static void rt2560_enable_tsf_sync(struct rt2560_softc *); static void rt2560_enable_tsf(struct rt2560_softc *); static void rt2560_update_plcp(struct rt2560_softc *); -static void rt2560_update_slot(struct ifnet *); +static void rt2560_update_slot(struct ieee80211com *); static void rt2560_set_basicrates(struct rt2560_softc *, const struct ieee80211_rateset *); static void rt2560_update_led(struct rt2560_softc *, int, int); static void rt2560_set_bssid(struct rt2560_softc *, const uint8_t *); -static void rt2560_set_macaddr(struct rt2560_softc *, uint8_t *); +static void rt2560_set_macaddr(struct rt2560_softc *, + const uint8_t *); static void rt2560_get_macaddr(struct rt2560_softc *, uint8_t *); -static void rt2560_update_promisc(struct ifnet *); +static void rt2560_update_promisc(struct ieee80211com *); static const char *rt2560_get_rf(int); static void rt2560_read_config(struct rt2560_softc *); static int rt2560_bbp_init(struct rt2560_softc *); @@ -185,6 +189,14 @@ static const uint32_t rt2560_rf2525e_r2[] = RT2560_RF2525E_R2; static const uint32_t rt2560_rf2526_r2[] = RT2560_RF2526_R2; static const uint32_t rt2560_rf2526_hi_r2[] = RT2560_RF2526_HI_R2; +static const uint8_t rt2560_chan_2ghz[] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; + +static const uint8_t rt2560_chan_5ghz[] = + { 36, 40, 44, 48, 52, 56, 60, 64, + 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, + 149, 153, 157, 161 }; + static const struct { uint8_t chan; uint32_t r1, r2, r4; @@ -196,11 +208,8 @@ int rt2560_attach(device_t dev, int id) { struct rt2560_softc *sc = device_get_softc(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; int error; - uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; @@ -208,6 +217,7 @@ rt2560_attach(device_t dev, int id) MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* retrieve RT2560 rev. no */ sc->asic_rev = RAL_READ(sc, RT2560_CSR0); @@ -251,27 +261,11 @@ rt2560_attach(device_t dev, int id) goto fail5; } - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - goto fail6; - } - ic = ifp->if_l2com; - /* retrieve MAC address */ - rt2560_get_macaddr(sc, macaddr); + rt2560_get_macaddr(sc, ic->ic_macaddr); - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rt2560_init; - ifp->if_ioctl = rt2560_ioctl; - ifp->if_start = rt2560_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; + ic->ic_softc = sc; + ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -293,23 +287,22 @@ rt2560_attach(device_t dev, int id) #endif ; - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - if (sc->rf_rev == RT2560_RF_5222) - setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, NULL, &bands); + rt2560_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, + ic->ic_channels); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_raw_xmit = rt2560_raw_xmit; ic->ic_updateslot = rt2560_update_slot; ic->ic_update_promisc = rt2560_update_promisc; ic->ic_scan_start = rt2560_scan_start; ic->ic_scan_end = rt2560_scan_end; + ic->ic_getradiocaps = rt2560_getradiocaps; ic->ic_set_channel = rt2560_set_channel; ic->ic_vap_create = rt2560_vap_create; ic->ic_vap_delete = rt2560_vap_delete; + ic->ic_parent = rt2560_parent; + ic->ic_transmit = rt2560_transmit; ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), @@ -338,7 +331,6 @@ rt2560_attach(device_t dev, int id) return 0; -fail6: rt2560_free_rx_ring(sc, &sc->rxq); fail5: rt2560_free_tx_ring(sc, &sc->bcnq); fail4: rt2560_free_tx_ring(sc, &sc->prioq); fail3: rt2560_free_tx_ring(sc, &sc->atimq); @@ -352,12 +344,12 @@ int rt2560_detach(void *xsc) { struct rt2560_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - + struct ieee80211com *ic = &sc->sc_ic; + rt2560_stop(sc); ieee80211_ifdetach(ic); + mbufq_drain(&sc->sc_snd); rt2560_free_tx_ring(sc, &sc->txq); rt2560_free_tx_ring(sc, &sc->atimq); @@ -365,8 +357,6 @@ rt2560_detach(void *xsc) rt2560_free_tx_ring(sc, &sc->bcnq); rt2560_free_rx_ring(sc, &sc->rxq); - if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; @@ -378,7 +368,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; + struct rt2560_softc *sc = ic->ic_softc; struct rt2560_vap *rvp; struct ieee80211vap *vap; @@ -391,7 +381,7 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - if_printf(ifp, "only 1 vap supported\n"); + device_printf(sc->sc_dev, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -400,7 +390,8 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - if_printf(ifp, "wds only supported in ap mode\n"); + device_printf(sc->sc_dev, + "wds only supported in ap mode\n"); return NULL; } /* @@ -411,15 +402,12 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - if_printf(ifp, "unknown opmode %d\n", opmode); + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); return NULL; } - rvp = (struct rt2560_vap *) malloc(sizeof(struct rt2560_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; + rvp = malloc(sizeof(struct rt2560_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -428,7 +416,8 @@ rt2560_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -448,9 +437,8 @@ void rt2560_resume(void *xsc) { struct rt2560_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) rt2560_init(sc); } @@ -476,7 +464,7 @@ rt2560_alloc_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring, ring->cur = ring->next = 0; ring->cur_encrypt = ring->next_encrypt = 0; - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, count * RT2560_TX_DESC_SIZE, 1, count * RT2560_TX_DESC_SIZE, 0, NULL, NULL, &ring->desc_dmat); @@ -508,7 +496,7 @@ rt2560_alloc_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring, goto fail; } - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, RT2560_MAX_SCATTER, MCLBYTES, 0, NULL, NULL, &ring->data_dmat); @@ -620,7 +608,7 @@ rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring, ring->cur = ring->next = 0; ring->cur_decrypt = 0; - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, count * RT2560_RX_DESC_SIZE, 1, count * RT2560_RX_DESC_SIZE, 0, NULL, NULL, &ring->desc_dmat); @@ -655,7 +643,7 @@ rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring, /* * Pre-allocate Rx buffers and populate Rx ring. */ - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, MCLBYTES, 0, NULL, NULL, &ring->data_dmat); if (error != 0) { @@ -760,8 +748,7 @@ static int rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2560_vap *rvp = RT2560_VAP(vap); - struct ifnet *ifp = vap->iv_ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = vap->iv_ic->ic_softc; int error; if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { @@ -787,9 +774,10 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) if (vap->iv_opmode == IEEE80211_M_HOSTAP || vap->iv_opmode == IEEE80211_M_IBSS || vap->iv_opmode == IEEE80211_M_MBSS) { - m = ieee80211_beacon_alloc(ni, &rvp->ral_bo); + m = ieee80211_beacon_alloc(ni); if (m == NULL) { - if_printf(ifp, "could not allocate beacon\n"); + device_printf(sc->sc_dev, + "could not allocate beacon\n"); return ENOBUFS; } ieee80211_ref_node(ni); @@ -798,7 +786,7 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) return error; } - /* turn assocation led on */ + /* turn association led on */ rt2560_update_led(sc, 1, 0); if (vap->iv_opmode != IEEE80211_M_MONITOR) @@ -923,14 +911,13 @@ rt2560_encryption_intr(struct rt2560_softc *sc) static void rt2560_tx_intr(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct mbuf *m; - uint32_t flags; - int retrycnt; struct ieee80211vap *vap; struct ieee80211_node *ni; + uint32_t flags; + int retrycnt, status; bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map, BUS_DMASYNC_POSTREAD); @@ -958,7 +945,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - ifp->if_opackets++; + status = 0; break; case RT2560_TX_SUCCESS_RETRY: @@ -970,7 +957,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - ifp->if_opackets++; + status = 0; break; case RT2560_TX_FAIL_RETRY: @@ -982,7 +969,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - ifp->if_oerrors++; + status = 1; break; case RT2560_TX_FAIL_INVALID: @@ -990,16 +977,16 @@ rt2560_tx_intr(struct rt2560_softc *sc) default: device_printf(sc->sc_dev, "sending data frame failed " "0x%08x\n", flags); - ifp->if_oerrors++; + status = 1; } bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->txq.data_dmat, data->map); - m_freem(m); - data->m = NULL; - ieee80211_free_node(data->ni); + + ieee80211_tx_complete(ni, m, status); data->ni = NULL; + data->m = NULL; /* descriptor is no longer valid */ desc->flags &= ~htole32(RT2560_TX_VALID); @@ -1016,19 +1003,13 @@ rt2560_tx_intr(struct rt2560_softc *sc) if (sc->prioq.queued == 0 && sc->txq.queued == 0) sc->sc_tx_timer = 0; - if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) { - sc->sc_flags &= ~RT2560_F_DATA_OACTIVE; - if ((sc->sc_flags & - (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2560_start_locked(ifp); - } + if (sc->txq.queued < RT2560_TX_RING_COUNT - 1) + rt2560_start(sc); } static void rt2560_prio_intr(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_node *ni; @@ -1100,13 +1081,8 @@ rt2560_prio_intr(struct rt2560_softc *sc) if (sc->prioq.queued == 0 && sc->txq.queued == 0) sc->sc_tx_timer = 0; - if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) { - sc->sc_flags &= ~RT2560_F_PRIO_OACTIVE; - if ((sc->sc_flags & - (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2560_start_locked(ifp); - } + if (sc->prioq.queued < RT2560_PRIO_RING_COUNT) + rt2560_start(sc); } /* @@ -1116,8 +1092,7 @@ rt2560_prio_intr(struct rt2560_softc *sc) static void rt2560_decryption_intr(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rt2560_rx_desc *desc; struct rt2560_rx_data *data; bus_addr_t physaddr; @@ -1127,7 +1102,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) int hw, error; int8_t rssi, nf; - /* retrieve last decriptor index processed by cipher engine */ + /* retrieve last descriptor index processed by cipher engine */ hw = RAL_READ(sc, RT2560_SECCSR0) - sc->rxq.physaddr; hw /= RT2560_RX_DESC_SIZE; @@ -1143,13 +1118,13 @@ rt2560_decryption_intr(struct rt2560_softc *sc) break; if (data->drop) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } if ((le32toh(desc->flags) & RT2560_RX_CIPHER_MASK) != 0 && (le32toh(desc->flags) & RT2560_RX_ICV_ERROR)) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1162,7 +1137,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1185,7 +1160,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1198,7 +1173,6 @@ rt2560_decryption_intr(struct rt2560_softc *sc) desc->physaddr = htole32(physaddr); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; @@ -1305,8 +1279,7 @@ rt2560_rx_intr(struct rt2560_softc *sc) static void rt2560_beacon_update(struct ieee80211vap *vap, int item) { - struct rt2560_vap *rvp = RT2560_VAP(vap); - struct ieee80211_beacon_offsets *bo = &rvp->ral_bo; + struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off; setbit(bo->bo_flags, item); } @@ -1318,16 +1291,13 @@ rt2560_beacon_update(struct ieee80211vap *vap, int item) static void rt2560_beacon_expire(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct rt2560_vap *rvp = RT2560_VAP(vap); + struct ieee80211com *ic = &sc->sc_ic; struct rt2560_tx_data *data; if (ic->ic_opmode != IEEE80211_M_IBSS && ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_MBSS) - return; + return; data = &sc->bcnq.data[sc->bcnq.next]; /* @@ -1340,7 +1310,7 @@ rt2560_beacon_expire(struct rt2560_softc *sc) bus_dmamap_unload(sc->bcnq.data_dmat, data->map); /* XXX 1 =>'s mcast frames which means all PS sta's will wakeup! */ - ieee80211_beacon_update(data->ni, &rvp->ral_bo, data->m, 1); + ieee80211_beacon_update(data->ni, data->m, 1); rt2560_tx_bcn(sc, data->m, data->ni); @@ -1360,7 +1330,6 @@ void rt2560_intr(void *arg) { struct rt2560_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t r; RAL_LOCK(sc); @@ -1370,7 +1339,7 @@ rt2560_intr(void *arg) RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); /* don't re-enable interrupts if we're shutting down */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RT2560_F_RUNNING)) { RAL_UNLOCK(sc); return; } @@ -1439,8 +1408,7 @@ static void rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t plcp_length; int remainder; @@ -1465,7 +1433,7 @@ rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, desc->plcp_length_hi = plcp_length >> 6; desc->plcp_length_lo = plcp_length & 0x3f; } else { - plcp_length = (16 * len + rate - 1) / rate; + plcp_length = howmany(16 * len, rate); if (rate == 22) { remainder = (16 * len) % 22; if (remainder != 0 && remainder < 7) @@ -1559,7 +1527,7 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); @@ -1805,7 +1773,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, rate = ni->ni_txrate; } - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); @@ -1915,55 +1883,57 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, return 0; } -static void -rt2560_start_locked(struct ifnet *ifp) +static int +rt2560_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct rt2560_softc *sc = ifp->if_softc; - struct mbuf *m; - struct ieee80211_node *ni; + struct rt2560_softc *sc = ic->ic_softc; + int error; - RAL_LOCK_ASSERT(sc); - - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->sc_flags |= RT2560_F_DATA_OACTIVE; - break; - } - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - if (rt2560_tx_data(sc, m, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } - - sc->sc_tx_timer = 5; + RAL_LOCK(sc); + if ((sc->sc_flags & RT2560_F_RUNNING) == 0) { + RAL_UNLOCK(sc); + return (ENXIO); } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RAL_UNLOCK(sc); + return (error); + } + rt2560_start(sc); + RAL_UNLOCK(sc); + + return (0); } static void -rt2560_start(struct ifnet *ifp) +rt2560_start(struct rt2560_softc *sc) { - struct rt2560_softc *sc = ifp->if_softc; + struct ieee80211_node *ni; + struct mbuf *m; - RAL_LOCK(sc); - rt2560_start_locked(ifp); - RAL_UNLOCK(sc); + RAL_LOCK_ASSERT(sc); + + while (sc->txq.queued < RT2560_TX_RING_COUNT - 1 && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + if (rt2560_tx_data(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); + ieee80211_free_node(ni); + break; + } + sc->sc_tx_timer = 5; + } } static void rt2560_watchdog(void *arg) { struct rt2560_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + KASSERT(sc->sc_flags & RT2560_F_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; @@ -1972,51 +1942,33 @@ rt2560_watchdog(void *arg) rt2560_tx_intr(sc); if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); + device_printf(sc->sc_dev, "device timeout\n"); rt2560_init_locked(sc); - ifp->if_oerrors++; + counter_u64_add(sc->sc_ic.ic_oerrors, 1); /* NB: callout is reset in rt2560_init() */ return; } callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); } -static int -rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rt2560_parent(struct ieee80211com *ic) { - struct rt2560_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct rt2560_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rt2560_init_locked(sc); - startall = 1; - } else - rt2560_update_promisc(ifp); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2560_stop_locked(sc); - } - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + RAL_LOCK(sc); + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & RT2560_F_RUNNING) == 0) { + rt2560_init_locked(sc); + startall = 1; + } else + rt2560_update_promisc(ic); + } else if (sc->sc_flags & RT2560_F_RUNNING) + rt2560_stop_locked(sc); + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -2100,8 +2052,7 @@ rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val) static void rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint8_t power, tmp; u_int i, chan; @@ -2177,7 +2128,7 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x00040); rt2560_rf_write(sc, RAL_RF4, rt2560_rf5222[i].r4); break; - default: + default: printf("unknown ral rev=%d\n", sc->rf_rev); } @@ -2197,11 +2148,30 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) } } +static void +rt2560_getradiocaps(struct ieee80211com *ic, + int maxchans, int *nchans, struct ieee80211_channel chans[]) +{ + struct rt2560_softc *sc = ic->ic_softc; + uint8_t bands[IEEE80211_MODE_BYTES]; + + memset(bands, 0, sizeof(bands)); + setbit(bands, IEEE80211_MODE_11B); + setbit(bands, IEEE80211_MODE_11G); + ieee80211_add_channel_list_2ghz(chans, maxchans, nchans, + rt2560_chan_2ghz, nitems(rt2560_chan_2ghz), bands, 0); + + if (sc->rf_rev == RT2560_RF_5222) { + setbit(bands, IEEE80211_MODE_11A); + ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, + rt2560_chan_5ghz, nitems(rt2560_chan_5ghz), bands, 0); + } +} + static void rt2560_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; RAL_LOCK(sc); rt2560_set_chan(sc, ic->ic_curchan); @@ -2237,8 +2207,7 @@ rt2560_disable_rf_tune(struct rt2560_softc *sc) static void rt2560_enable_tsf_sync(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t logcwmin, preload; uint32_t tmp; @@ -2279,8 +2248,7 @@ rt2560_enable_tsf(struct rt2560_softc *sc) static void rt2560_update_plcp(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* no short preamble for 1Mbps */ RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400); @@ -2306,16 +2274,15 @@ rt2560_update_plcp(struct rt2560_softc *sc) * IEEE Std 802.11-1999 pp. 85 to know how these values are computed. */ static void -rt2560_update_slot(struct ifnet *ifp) +rt2560_update_slot(struct ieee80211com *ic) { - struct rt2560_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct rt2560_softc *sc = ic->ic_softc; uint8_t slottime; uint16_t tx_sifs, tx_pifs, tx_difs, eifs; uint32_t tmp; #ifndef FORCE_SLOTTIME - slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; + slottime = IEEE80211_GET_SLOTTIME(ic); #else /* * Setting slot time according to "short slot time" capability @@ -2333,13 +2300,13 @@ rt2560_update_slot(struct ifnet *ifp) * (-1Mb~-2Mb lower) and the _whole_ BSS would stop using short * slot time. */ - slottime = 20; + slottime = IEEE80211_DUR_SLOT; #endif /* update the MAC slot boundaries */ tx_sifs = RAL_SIFS - RT2560_TXRX_TURNAROUND; tx_pifs = tx_sifs + slottime; - tx_difs = tx_sifs + 2 * slottime; + tx_difs = IEEE80211_DUR_DIFS(tx_sifs, slottime); eifs = (ic->ic_curmode == IEEE80211_MODE_11B) ? 364 : 60; tmp = RAL_READ(sc, RT2560_CSR11); @@ -2359,9 +2326,7 @@ static void rt2560_set_basicrates(struct rt2560_softc *sc, const struct ieee80211_rateset *rs) { -#define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mask = 0; uint8_t rate; int i; @@ -2372,13 +2337,13 @@ rt2560_set_basicrates(struct rt2560_softc *sc, if (!(rate & IEEE80211_RATE_BASIC)) continue; - mask |= 1 << ic->ic_rt->rateCodeToIndex[RV(rate)]; + mask |= 1 << ieee80211_legacy_rate_lookup(ic->ic_rt, + IEEE80211_RV(rate)); } RAL_WRITE(sc, RT2560_ARSP_PLCP_1, mask); DPRINTF(sc, "Setting basic rate mask to 0x%x\n", mask); -#undef RV } static void @@ -2406,7 +2371,7 @@ rt2560_set_bssid(struct rt2560_softc *sc, const uint8_t *bssid) } static void -rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr) +rt2560_set_macaddr(struct rt2560_softc *sc, const uint8_t *addr) { uint32_t tmp; @@ -2436,21 +2401,21 @@ rt2560_get_macaddr(struct rt2560_softc *sc, uint8_t *addr) } static void -rt2560_update_promisc(struct ifnet *ifp) +rt2560_update_promisc(struct ieee80211com *ic) { - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2560_RXCSR0); tmp &= ~RT2560_DROP_NOT_TO_ME; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2560_DROP_NOT_TO_ME; RAL_WRITE(sc, RT2560_RXCSR0, tmp); - DPRINTF(sc, "%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? - "entering" : "leaving"); + DPRINTF(sc, "%s promiscuous mode\n", + (ic->ic_promisc > 0) ? "entering" : "leaving"); } static const char * @@ -2516,19 +2481,17 @@ rt2560_read_config(struct rt2560_softc *sc) static void rt2560_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; /* abort TSF synchronization */ RAL_WRITE(sc, RT2560_CSR14, 0); - rt2560_set_bssid(sc, ifp->if_broadcastaddr); + rt2560_set_bssid(sc, ieee80211broadcastaddr); } static void rt2560_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; struct ieee80211vap *vap = ic->ic_scan->ss_vap; rt2560_enable_tsf_sync(sc); @@ -2539,7 +2502,6 @@ rt2560_scan_end(struct ieee80211com *ic) static int rt2560_bbp_init(struct rt2560_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) int i, ntries; /* wait for BBP to be ready */ @@ -2554,7 +2516,7 @@ rt2560_bbp_init(struct rt2560_softc *sc) } /* initialize BBP registers to default values */ - for (i = 0; i < N(rt2560_def_bbp); i++) { + for (i = 0; i < nitems(rt2560_def_bbp); i++) { rt2560_bbp_write(sc, rt2560_def_bbp[i].reg, rt2560_def_bbp[i].val); } @@ -2568,7 +2530,6 @@ rt2560_bbp_init(struct rt2560_softc *sc) rt2560_bbp_write(sc, 17, 0x48); /* XXX restore bbp17 */ return 0; -#undef N } static void @@ -2621,9 +2582,8 @@ rt2560_set_rxantenna(struct rt2560_softc *sc, int antenna) static void rt2560_init_locked(struct rt2560_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; int i; @@ -2651,15 +2611,15 @@ rt2560_init_locked(struct rt2560_softc *sc) RAL_WRITE(sc, RT2560_RXCSR2, sc->rxq.physaddr); /* initialize MAC registers to default values */ - for (i = 0; i < N(rt2560_def_mac); i++) + for (i = 0; i < nitems(rt2560_def_mac); i++) RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val); - rt2560_set_macaddr(sc, IF_LLADDR(ifp)); + rt2560_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* set basic rate set (will be updated later) */ RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153); - rt2560_update_slot(ifp); + rt2560_update_slot(ic); rt2560_update_plcp(sc); rt2560_update_led(sc, 0, 0); @@ -2684,7 +2644,7 @@ rt2560_init_locked(struct rt2560_softc *sc) if (ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_MBSS) tmp |= RT2560_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2560_DROP_NOT_TO_ME; } RAL_WRITE(sc, RT2560_RXCSR0, tmp); @@ -2699,32 +2659,28 @@ rt2560_init_locked(struct rt2560_softc *sc) /* enable interrupts */ RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= RT2560_F_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); -#undef N } static void rt2560_init(void *priv) { struct rt2560_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; RAL_LOCK(sc); rt2560_init_locked(sc); RAL_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RT2560_F_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } static void rt2560_stop_locked(struct rt2560_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; volatile int *flags = &sc->sc_flags; RAL_LOCK_ASSERT(sc); @@ -2735,12 +2691,12 @@ rt2560_stop_locked(struct rt2560_softc *sc) callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + if (sc->sc_flags & RT2560_F_RUNNING) { + sc->sc_flags &= ~RT2560_F_RUNNING; /* abort Tx */ RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX); - + /* disable Rx */ RAL_WRITE(sc, RT2560_RXCSR0, RT2560_DISABLE_RX); @@ -2750,7 +2706,7 @@ rt2560_stop_locked(struct rt2560_softc *sc) /* disable interrupts */ RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); - + /* reset Tx and Rx rings */ rt2560_reset_tx_ring(sc, &sc->txq); rt2560_reset_tx_ring(sc, &sc->atimq); @@ -2758,7 +2714,6 @@ rt2560_stop_locked(struct rt2560_softc *sc) rt2560_reset_tx_ring(sc, &sc->bcnq); rt2560_reset_rx_ring(sc, &sc->rxq); } - sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE); } void @@ -2776,29 +2731,22 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rt2560_softc *sc = ifp->if_softc; + struct rt2560_softc *sc = ic->ic_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RT2560_F_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); - ieee80211_free_node(ni); return ENETDOWN; } if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->sc_flags |= RT2560_F_PRIO_OACTIVE; RAL_UNLOCK(sc); m_freem(m); - ieee80211_free_node(ni); return ENOBUFS; /* XXX */ } - ifp->if_opackets++; - if (params == NULL) { /* * Legacy path; interpret frame contents to decide @@ -2820,8 +2768,6 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: - ifp->if_oerrors++; - ieee80211_free_node(ni); RAL_UNLOCK(sc); return EIO; /* XXX */ } diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560reg.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560reg.h index 8e501b4c22..ae46b5f912 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560reg.h +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560reg.h @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ral/rt2560reg.h 258780 2013-11-30 22:17:27Z eadler $ */ /*- * Copyright (c) 2005, 2006 @@ -268,7 +268,7 @@ struct rt2560_rx_desc { #define RT2560_BBP_BUSY (1 << 15) #define RT2560_BBP_WRITE (1 << 16) #define RT2560_RF_20BIT (20 << 24) -#define RT2560_RF_BUSY (1 << 31) +#define RT2560_RF_BUSY (1U << 31) #define RT2560_RF_2522 0x00 #define RT2560_RF_2523 0x01 diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560var.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560var.h index b6a8d68e92..364a85655d 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560var.h +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2560var.h @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ral/rt2560var.h 289168 2015-10-12 05:21:51Z adrian $ */ /*- * Copyright (c) 2005, 2006 @@ -97,7 +97,6 @@ struct rt2560_rx_ring { struct rt2560_vap { struct ieee80211vap ral_vap; - struct ieee80211_beacon_offsets ral_bo; int (*ral_newstate)(struct ieee80211vap *, enum ieee80211_state, int); @@ -105,13 +104,13 @@ struct rt2560_vap { #define RT2560_VAP(vap) ((struct rt2560_vap *)(vap)) struct rt2560_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mtx sc_mtx; + struct mbufq sc_snd; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; - struct mtx sc_mtx; - struct callout watchdog_ch; int sc_tx_timer; @@ -147,13 +146,10 @@ struct rt2560_softc { int nb_ant; struct rt2560_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - struct rt2560_tx_radiotap_header sc_txtap; - int sc_txtap_len; + #define RT2560_F_INPUT_RUNNING 0x1 -#define RT2560_F_PRIO_OACTIVE 0x2 -#define RT2560_F_DATA_OACTIVE 0x4 +#define RT2560_F_RUNNING 0x2 int sc_flags; }; diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c index 5210969dbe..65356530ab 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661.c @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ral/rt2661.c 314222 2017-02-24 21:19:40Z avos $ */ /*- * Copyright (c) 2006 @@ -18,7 +18,7 @@ */ #include -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: releng/11.1/sys/dev/ral/rt2661.c 314222 2017-02-24 21:19:40Z avos $"); /*- * Ralink Technology RT2561, RT2561S and RT2661 chipset driver @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -112,6 +113,8 @@ static void rt2661_mcu_wakeup(struct rt2661_softc *); static void rt2661_mcu_cmd_intr(struct rt2661_softc *); static void rt2661_scan_start(struct ieee80211com *); static void rt2661_scan_end(struct ieee80211com *); +static void rt2661_getradiocaps(struct ieee80211com *, int, int *, + struct ieee80211_channel[]); static void rt2661_set_channel(struct ieee80211com *); static void rt2661_setup_tx_desc(struct rt2661_softc *, struct rt2661_tx_desc *, uint32_t, uint16_t, int, @@ -120,12 +123,12 @@ static int rt2661_tx_data(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *, int); static int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *); -static void rt2661_start_locked(struct ifnet *); -static void rt2661_start(struct ifnet *); +static int rt2661_transmit(struct ieee80211com *, struct mbuf *); +static void rt2661_start(struct rt2661_softc *); static int rt2661_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static void rt2661_watchdog(void *); -static int rt2661_ioctl(struct ifnet *, u_long, caddr_t); +static void rt2661_parent(struct ieee80211com *); static void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t); static uint8_t rt2661_bbp_read(struct rt2661_softc *, uint8_t); @@ -146,9 +149,9 @@ static void rt2661_set_bssid(struct rt2661_softc *, const uint8_t *); static void rt2661_set_macaddr(struct rt2661_softc *, const uint8_t *); -static void rt2661_update_promisc(struct ifnet *); +static void rt2661_update_promisc(struct ieee80211com *); static int rt2661_wme_update(struct ieee80211com *) __unused; -static void rt2661_update_slot(struct ifnet *); +static void rt2661_update_slot(struct ieee80211com *); static const char *rt2661_get_rf(int); static void rt2661_read_eeprom(struct rt2661_softc *, uint8_t macaddr[IEEE80211_ADDR_LEN]); @@ -192,31 +195,29 @@ static const struct rfprog { RT2661_RF5225_2 }; +static const uint8_t rt2661_chan_2ghz[] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; +static const uint8_t rt2661_chan_5ghz[] = + { 36, 40, 44, 48, 52, 56, 60, 64, + 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, + 149, 153, 157, 161, 165 }; + int rt2661_attach(device_t dev, int id) { struct rt2661_softc *sc = device_get_softc(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint32_t val; int error, ac, ntries; - uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_id = id; sc->sc_dev = dev; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - return ENOMEM; - } - ic = ifp->if_l2com; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* wait for NIC to initialize */ for (ntries = 0; ntries < 1000; ntries++) { @@ -232,7 +233,7 @@ rt2661_attach(device_t dev, int id) } /* retrieve RF rev. no and various other things from EEPROM */ - rt2661_read_eeprom(sc, macaddr); + rt2661_read_eeprom(sc, ic->ic_macaddr); device_printf(dev, "MAC/BBP RT%X, RF %s\n", val, rt2661_get_rf(sc->rf_rev)); @@ -262,17 +263,8 @@ rt2661_attach(device_t dev, int id) goto fail3; } - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rt2661_init; - ifp->if_ioctl = rt2661_ioctl; - ifp->if_start = rt2661_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; + ic->ic_softc = sc; + ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -295,24 +287,22 @@ rt2661_attach(device_t dev, int id) #endif ; - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - if (sc->rf_rev == RT2661_RF_5225 || sc->rf_rev == RT2661_RF_5325) - setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, NULL, &bands); + rt2661_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, + ic->ic_channels); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); #if 0 ic->ic_wme.wme_update = rt2661_wme_update; #endif ic->ic_scan_start = rt2661_scan_start; ic->ic_scan_end = rt2661_scan_end; + ic->ic_getradiocaps = rt2661_getradiocaps; ic->ic_set_channel = rt2661_set_channel; ic->ic_updateslot = rt2661_update_slot; ic->ic_update_promisc = rt2661_update_promisc; ic->ic_raw_xmit = rt2661_raw_xmit; - + ic->ic_transmit = rt2661_transmit; + ic->ic_parent = rt2661_parent; ic->ic_vap_create = rt2661_vap_create; ic->ic_vap_delete = rt2661_vap_delete; @@ -336,7 +326,6 @@ fail3: rt2661_free_tx_ring(sc, &sc->mgtq); fail2: while (--ac >= 0) rt2661_free_tx_ring(sc, &sc->txq[ac]); fail1: mtx_destroy(&sc->sc_mtx); - if_free(ifp); return error; } @@ -344,14 +333,14 @@ int rt2661_detach(void *xsc) { struct rt2661_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - + struct ieee80211com *ic = &sc->sc_ic; + RAL_LOCK(sc); rt2661_stop_locked(sc); RAL_UNLOCK(sc); ieee80211_ifdetach(ic); + mbufq_drain(&sc->sc_snd); rt2661_free_tx_ring(sc, &sc->txq[0]); rt2661_free_tx_ring(sc, &sc->txq[1]); @@ -360,8 +349,6 @@ rt2661_detach(void *xsc) rt2661_free_tx_ring(sc, &sc->mgtq); rt2661_free_rx_ring(sc, &sc->rxq); - if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; @@ -373,7 +360,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; + struct rt2661_softc *sc = ic->ic_softc; struct rt2661_vap *rvp; struct ieee80211vap *vap; @@ -386,7 +373,7 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - if_printf(ifp, "only 1 vap supported\n"); + device_printf(sc->sc_dev, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -395,7 +382,8 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - if_printf(ifp, "wds only supported in ap mode\n"); + device_printf(sc->sc_dev, + "wds only supported in ap mode\n"); return NULL; } /* @@ -406,15 +394,12 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - if_printf(ifp, "unknown opmode %d\n", opmode); + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); return NULL; } - rvp = (struct rt2661_vap *) malloc(sizeof(struct rt2661_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; + rvp = malloc(sizeof(struct rt2661_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -425,7 +410,8 @@ rt2661_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -461,9 +447,8 @@ void rt2661_resume(void *xsc) { struct rt2661_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) rt2661_init(sc); } @@ -488,7 +473,7 @@ rt2661_alloc_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring, ring->queued = 0; ring->cur = ring->next = ring->stat = 0; - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, count * RT2661_TX_DESC_SIZE, 1, count * RT2661_TX_DESC_SIZE, 0, NULL, NULL, &ring->desc_dmat); @@ -520,7 +505,7 @@ rt2661_alloc_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring, goto fail; } - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, RT2661_MAX_SCATTER, MCLBYTES, 0, NULL, NULL, &ring->data_dmat); if (error != 0) { @@ -629,7 +614,7 @@ rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring, ring->count = count; ring->cur = ring->next = 0; - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, count * RT2661_RX_DESC_SIZE, 1, count * RT2661_RX_DESC_SIZE, 0, NULL, NULL, &ring->desc_dmat); @@ -664,7 +649,7 @@ rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring, /* * Pre-allocate Rx buffers and populate Rx ring. */ - error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, + error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, MCLBYTES, 0, NULL, NULL, &ring->data_dmat); if (error != 0) { @@ -767,7 +752,7 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2661_vap *rvp = RT2661_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rt2661_softc *sc = ic->ic_ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; int error; if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { @@ -866,11 +851,10 @@ rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr) static void rt2661_tx_intr(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct rt2661_tx_ring *txq; struct rt2661_tx_data *data; uint32_t val; - int qid, retrycnt; + int error, qid, retrycnt; struct ieee80211vap *vap; for (;;) { @@ -908,7 +892,7 @@ rt2661_tx_intr(struct rt2661_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_SUCCESS, &retrycnt, NULL); - ifp->if_opackets++; + error = 0; break; case RT2661_TX_RETRY_FAIL: @@ -920,14 +904,14 @@ rt2661_tx_intr(struct rt2661_softc *sc) ieee80211_ratectl_tx_complete(vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - ifp->if_oerrors++; + error = 1; break; default: /* other failure */ device_printf(sc->sc_dev, "sending data frame failed 0x%08x\n", val); - ifp->if_oerrors++; + error = 1; } DPRINTFN(sc, 15, "tx done q=%d idx=%u\n", qid, txq->stat); @@ -936,17 +920,12 @@ rt2661_tx_intr(struct rt2661_softc *sc) if (++txq->stat >= txq->count) /* faster than % count */ txq->stat = 0; - if (m->m_flags & M_TXCB) - ieee80211_process_callback(ni, m, - RT2661_TX_RESULT(val) != RT2661_TX_SUCCESS); - m_freem(m); - ieee80211_free_node(ni); + ieee80211_tx_complete(ni, m, error); } sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2661_start_locked(ifp); + rt2661_start(sc); } static void @@ -984,8 +963,7 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq) static void rt2661_rx_intr(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rt2661_rx_desc *desc; struct rt2661_rx_data *data; bus_addr_t physaddr; @@ -1014,12 +992,12 @@ rt2661_rx_intr(struct rt2661_softc *sc) */ DPRINTFN(sc, 5, "PHY or CRC error flags 0x%08x\n", le32toh(desc->flags)); - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } if ((le32toh(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1032,7 +1010,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) */ mnew = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (mnew == NULL) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1055,7 +1033,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) panic("%s: could not load old rx mbuf", device_get_name(sc->sc_dev)); } - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1068,7 +1046,6 @@ rt2661_rx_intr(struct rt2661_softc *sc) desc->physaddr = htole32(physaddr); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; @@ -1153,7 +1130,6 @@ void rt2661_intr(void *arg) { struct rt2661_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; uint32_t r1, r2; RAL_LOCK(sc); @@ -1164,7 +1140,7 @@ rt2661_intr(void *arg) RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); /* don't re-enable interrupts if we're shutting down */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RAL_RUNNING)) { RAL_UNLOCK(sc); return; } @@ -1241,8 +1217,7 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate, const bus_dma_segment_t *segs, int nsegs, int ac) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint16_t plcp_length; int i, remainder; @@ -1278,7 +1253,7 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, desc->plcp_length_hi = plcp_length >> 6; desc->plcp_length_lo = plcp_length & 0x3f; } else { - plcp_length = (16 * len + rate - 1) / rate; + plcp_length = howmany(16 * len, rate); if (rate == 22) { remainder = (16 * len) % 22; if (remainder != 0 && remainder < 7) @@ -1320,7 +1295,7 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); @@ -1460,8 +1435,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, int ac) { struct ieee80211vap *vap = ni->ni_vap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct rt2661_tx_ring *txq = &sc->txq[ac]; struct rt2661_tx_desc *desc; struct rt2661_tx_data *data; @@ -1495,7 +1469,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, noack = cap->cap_wmeParams[ac].wmep_noackPolicy; } - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); @@ -1603,10 +1577,31 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, return 0; } -static void -rt2661_start_locked(struct ifnet *ifp) +static int +rt2661_transmit(struct ieee80211com *ic, struct mbuf *m) +{ + struct rt2661_softc *sc = ic->ic_softc; + int error; + + RAL_LOCK(sc); + if ((sc->sc_flags & RAL_RUNNING) == 0) { + RAL_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RAL_UNLOCK(sc); + return (error); + } + rt2661_start(sc); + RAL_UNLOCK(sc); + + return (0); +} + +static void +rt2661_start(struct rt2661_softc *sc) { - struct rt2661_softc *sc = ifp->if_softc; struct mbuf *m; struct ieee80211_node *ni; int ac; @@ -1614,69 +1609,48 @@ rt2661_start_locked(struct ifnet *ifp) RAL_LOCK_ASSERT(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid) + if (!(sc->sc_flags & RAL_RUNNING) || sc->sc_invalid) return; - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - + while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ac = M_WME_GETAC(m); if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) { /* there is no place left in this ring */ - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; + mbufq_prepend(&sc->sc_snd, m); break; } ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (rt2661_tx_data(sc, m, ni, ac) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - ifp->if_oerrors++; break; } - sc->sc_tx_timer = 5; } } -static void -rt2661_start(struct ifnet *ifp) -{ - struct rt2661_softc *sc = ifp->if_softc; - - RAL_LOCK(sc); - rt2661_start_locked(ifp); - RAL_UNLOCK(sc); -} - static int rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RAL_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); - ieee80211_free_node(ni); return ENETDOWN; } if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; RAL_UNLOCK(sc); m_freem(m); - ieee80211_free_node(ni); return ENOBUFS; /* XXX */ } - ifp->if_opackets++; - /* * Legacy path; interpret frame contents to decide * precisely how to send the frame. @@ -1690,8 +1664,6 @@ rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; bad: - ifp->if_oerrors++; - ieee80211_free_node(ni); RAL_UNLOCK(sc); return EIO; /* XXX */ } @@ -1700,61 +1672,42 @@ static void rt2661_watchdog(void *arg) { struct rt2661_softc *sc = (struct rt2661_softc *)arg; - struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + KASSERT(sc->sc_flags & RAL_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); + device_printf(sc->sc_dev, "device timeout\n"); rt2661_init_locked(sc); - ifp->if_oerrors++; + counter_u64_add(sc->sc_ic.ic_oerrors, 1); /* NB: callout is reset in rt2661_init() */ return; } callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); } -static int -rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rt2661_parent(struct ieee80211com *ic) { - struct rt2661_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; + struct rt2661_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - rt2661_init_locked(sc); - startall = 1; - } else - rt2661_update_promisc(ifp); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2661_stop_locked(sc); - } - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + RAL_LOCK(sc); + if (ic->ic_nrunning > 0) { + if ((sc->sc_flags & RAL_RUNNING) == 0) { + rt2661_init_locked(sc); + startall = 1; + } else + rt2661_update_promisc(ic); + } else if (sc->sc_flags & RAL_RUNNING) + rt2661_stop_locked(sc); + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } static void @@ -1878,8 +1831,7 @@ rt2661_select_antenna(struct rt2661_softc *sc) static void rt2661_enable_mrr(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); @@ -1895,8 +1847,7 @@ rt2661_enable_mrr(struct rt2661_softc *sc) static void rt2661_set_txpreamble(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); @@ -1912,9 +1863,7 @@ static void rt2661_set_basicrates(struct rt2661_softc *sc, const struct ieee80211_rateset *rs) { -#define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mask = 0; uint8_t rate; int i; @@ -1925,13 +1874,13 @@ rt2661_set_basicrates(struct rt2661_softc *sc, if (!(rate & IEEE80211_RATE_BASIC)) continue; - mask |= 1 << ic->ic_rt->rateCodeToIndex[RV(rate)]; + mask |= 1 << ieee80211_legacy_rate_lookup(ic->ic_rt, + IEEE80211_RV(rate)); } RAL_WRITE(sc, RT2661_TXRX_CSR5, mask); DPRINTF(sc, "Setting basic rate mask to 0x%x\n", mask); -#undef RV } /* @@ -1983,8 +1932,7 @@ rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c) static void rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT; int8_t power; @@ -2079,21 +2027,21 @@ rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr) } static void -rt2661_update_promisc(struct ifnet *ifp) +rt2661_update_promisc(struct ieee80211com *ic) { - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR0); tmp &= ~RT2661_DROP_NOT_TO_ME; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2661_DROP_NOT_TO_ME; RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp); - DPRINTF(sc, "%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? - "entering" : "leaving"); + DPRINTF(sc, "%s promiscuous mode\n", + (ic->ic_promisc > 0) ? "entering" : "leaving"); } /* @@ -2102,7 +2050,7 @@ rt2661_update_promisc(struct ifnet *ifp) static int rt2661_wme_update(struct ieee80211com *ic) { - struct rt2661_softc *sc = ic->ic_ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; const struct wmeParams *wmep; wmep = ic->ic_wme.wme_chanParams.cap_wmeParams; @@ -2143,14 +2091,13 @@ rt2661_wme_update(struct ieee80211com *ic) } static void -rt2661_update_slot(struct ifnet *ifp) +rt2661_update_slot(struct ieee80211com *ic) { - struct rt2661_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct rt2661_softc *sc = ic->ic_softc; uint8_t slottime; uint32_t tmp; - slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; + slottime = IEEE80211_GET_SLOTTIME(ic); tmp = RAL_READ(sc, RT2661_MAC_CSR9); tmp = (tmp & ~0xff) | slottime; @@ -2264,7 +2211,6 @@ rt2661_read_eeprom(struct rt2661_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) static int rt2661_bbp_init(struct rt2661_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) int i, ntries; uint8_t val; @@ -2281,7 +2227,7 @@ rt2661_bbp_init(struct rt2661_softc *sc) } /* initialize BBP registers to default values */ - for (i = 0; i < N(rt2661_def_bbp); i++) { + for (i = 0; i < nitems(rt2661_def_bbp); i++) { rt2661_bbp_write(sc, rt2661_def_bbp[i].reg, rt2661_def_bbp[i].val); } @@ -2294,15 +2240,13 @@ rt2661_bbp_init(struct rt2661_softc *sc) } return 0; -#undef N } static void rt2661_init_locked(struct rt2661_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp, sta[3]; int i, error, ntries; @@ -2311,7 +2255,7 @@ rt2661_init_locked(struct rt2661_softc *sc) if ((sc->sc_flags & RAL_FW_LOADED) == 0) { error = rt2661_load_microcode(sc); if (error != 0) { - if_printf(ifp, + device_printf(sc->sc_dev, "%s: could not load 8051 microcode, error %d\n", __func__, error); return; @@ -2361,10 +2305,10 @@ rt2661_init_locked(struct rt2661_softc *sc) RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 2); /* initialize MAC registers to default values */ - for (i = 0; i < N(rt2661_def_mac); i++) + for (i = 0; i < nitems(rt2661_def_mac); i++) RAL_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val); - rt2661_set_macaddr(sc, IF_LLADDR(ifp)); + rt2661_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* set host ready */ RAL_WRITE(sc, RT2661_MAC_CSR1, 3); @@ -2403,14 +2347,14 @@ rt2661_init_locked(struct rt2661_softc *sc) if (ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_MBSS) tmp |= RT2661_DROP_TODS; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2661_DROP_NOT_TO_ME; } RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp); /* clear STA registers */ - RAL_READ_REGION_4(sc, RT2661_STA_CSR0, sta, N(sta)); + RAL_READ_REGION_4(sc, RT2661_STA_CSR0, sta, nitems(sta)); /* initialize ASIC */ RAL_WRITE(sc, RT2661_MAC_CSR1, 4); @@ -2425,34 +2369,30 @@ rt2661_init_locked(struct rt2661_softc *sc) /* kick Rx */ RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= RAL_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); -#undef N } static void rt2661_init(void *priv) { struct rt2661_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; RAL_LOCK(sc); rt2661_init_locked(sc); RAL_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RAL_RUNNING) ieee80211_start_all(ic); /* start all vap's */ } void rt2661_stop_locked(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - uint32_t tmp; volatile int *flags = &sc->sc_flags; + uint32_t tmp; while (*flags & RAL_INPUT_RUNNING) msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10); @@ -2460,28 +2400,28 @@ rt2661_stop_locked(struct rt2661_softc *sc) callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + if (sc->sc_flags & RAL_RUNNING) { + sc->sc_flags &= ~RAL_RUNNING; /* abort Tx (for all 5 Tx rings) */ RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16); - + /* disable Rx (value remains after reset!) */ tmp = RAL_READ(sc, RT2661_TXRX_CSR0); RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX); - + /* reset ASIC */ RAL_WRITE(sc, RT2661_MAC_CSR1, 3); RAL_WRITE(sc, RT2661_MAC_CSR1, 0); - + /* disable interrupts */ RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffffff); RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); - + /* clear any pending interrupt */ RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff); RAL_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff); - + /* reset Tx and Rx rings */ rt2661_reset_tx_ring(sc, &sc->txq[0]); rt2661_reset_tx_ring(sc, &sc->txq[1]); @@ -2505,7 +2445,6 @@ rt2661_stop(void *priv) static int rt2661_load_microcode(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; const struct firmware *fp; const char *imagename; int ntries, error; @@ -2517,7 +2456,7 @@ rt2661_load_microcode(struct rt2661_softc *sc) case 0x0302: imagename = "rt2561fw"; break; case 0x0401: imagename = "rt2661fw"; break; default: - if_printf(ifp, "%s: unexpected pci device id 0x%x, " + device_printf(sc->sc_dev, "%s: unexpected pci device id 0x%x, " "don't know how to retrieve firmware\n", __func__, sc->sc_id); return EINVAL; @@ -2526,7 +2465,8 @@ rt2661_load_microcode(struct rt2661_softc *sc) fp = firmware_get(imagename); RAL_LOCK(sc); if (fp == NULL) { - if_printf(ifp, "%s: unable to retrieve firmware image %s\n", + device_printf(sc->sc_dev, + "%s: unable to retrieve firmware image %s\n", __func__, imagename); return EINVAL; } @@ -2557,8 +2497,8 @@ rt2661_load_microcode(struct rt2661_softc *sc) DELAY(100); } if (ntries == 500) { - if_printf(ifp, "%s: timeout waiting for MCU to initialize\n", - __func__); + device_printf(sc->sc_dev, + "%s: timeout waiting for MCU to initialize\n", __func__); error = EIO; } else error = 0; @@ -2690,13 +2630,11 @@ static int rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_beacon_offsets bo; struct rt2661_tx_desc desc; struct mbuf *m0; int rate; - m0 = ieee80211_beacon_alloc(vap->iv_bss, &bo); - if (m0 == NULL) { + if ((m0 = ieee80211_beacon_alloc(vap->iv_bss))== NULL) { device_printf(sc->sc_dev, "could not allocate beacon frame\n"); return ENOBUFS; } @@ -2726,8 +2664,7 @@ rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap) static void rt2661_enable_tsf_sync(struct rt2661_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; @@ -2756,7 +2693,7 @@ rt2661_enable_tsf_sync(struct rt2661_softc *sc) static void rt2661_enable_tsf(struct rt2661_softc *sc) { - RAL_WRITE(sc, RT2661_TXRX_CSR9, + RAL_WRITE(sc, RT2661_TXRX_CSR9, (RAL_READ(sc, RT2661_TXRX_CSR9) & 0xff000000) | RT2661_TSF_TICKING | RT2661_TSF_MODE(2)); } @@ -2811,21 +2748,19 @@ rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw) static void rt2661_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; uint32_t tmp; /* abort TSF synchronization */ tmp = RAL_READ(sc, RT2661_TXRX_CSR9); RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0xffffff); - rt2661_set_bssid(sc, ifp->if_broadcastaddr); + rt2661_set_bssid(sc, ieee80211broadcastaddr); } static void rt2661_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); rt2661_enable_tsf_sync(sc); @@ -2833,11 +2768,30 @@ rt2661_scan_end(struct ieee80211com *ic) rt2661_set_bssid(sc, vap->iv_bss->ni_bssid); } +static void +rt2661_getradiocaps(struct ieee80211com *ic, + int maxchans, int *nchans, struct ieee80211_channel chans[]) +{ + struct rt2661_softc *sc = ic->ic_softc; + uint8_t bands[IEEE80211_MODE_BYTES]; + + memset(bands, 0, sizeof(bands)); + setbit(bands, IEEE80211_MODE_11B); + setbit(bands, IEEE80211_MODE_11G); + ieee80211_add_channel_list_2ghz(chans, maxchans, nchans, + rt2661_chan_2ghz, nitems(rt2661_chan_2ghz), bands, 0); + + if (sc->rf_rev == RT2661_RF_5225 || sc->rf_rev == RT2661_RF_5325) { + setbit(bands, IEEE80211_MODE_11A); + ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, + rt2661_chan_5ghz, nitems(rt2661_chan_5ghz), bands, 0); + } +} + static void rt2661_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2661_softc *sc = ifp->if_softc; + struct rt2661_softc *sc = ic->ic_softc; RAL_LOCK(sc); rt2661_set_chan(sc, ic->ic_curchan); diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661reg.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661reg.h index b4325b053d..417365d408 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661reg.h +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661reg.h @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ral/rt2661reg.h 258780 2013-11-30 22:17:27Z eadler $ */ /*- * Copyright (c) 2006 @@ -182,7 +182,7 @@ /* possible flags for register PHY_CSR4 */ #define RT2661_RF_21BIT (21 << 24) -#define RT2661_RF_BUSY (1 << 31) +#define RT2661_RF_BUSY (1U << 31) /* possible values for register STA_CSR4 */ #define RT2661_TX_STAT_VALID (1 << 0) diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661var.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661var.h index 9927d138fa..975add1254 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661var.h +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2661var.h @@ -1,4 +1,4 @@ -/* $FreeBSD$ */ +/* $FreeBSD: releng/11.1/sys/dev/ral/rt2661var.h 300657 2016-05-25 06:29:23Z sgalabov $ */ /*- * Copyright (c) 2005 @@ -26,7 +26,7 @@ struct rt2661_rx_radiotap_header { uint16_t wr_chan_flags; int8_t wr_antsignal; int8_t wr_antnoise; -} __packed; +} __packed __aligned(8); #define RT2661_RX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_TSFT) | \ @@ -42,7 +42,7 @@ struct rt2661_tx_radiotap_header { uint8_t wt_rate; uint16_t wt_chan_freq; uint16_t wt_chan_flags; -} __packed; +} __packed __aligned(8); #define RT2661_TX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ @@ -97,13 +97,13 @@ struct rt2661_vap { #define RT2661_VAP(vap) ((struct rt2661_vap *)(vap)) struct rt2661_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mtx sc_mtx; + struct mbufq sc_snd; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; - struct mtx sc_mtx; - struct callout watchdog_ch; int sc_tx_timer; @@ -117,6 +117,7 @@ struct rt2661_softc { int sc_flags; #define RAL_FW_LOADED 0x1 #define RAL_INPUT_RUNNING 0x2 +#define RAL_RUNNING 0x4 int sc_id; struct ieee80211_channel *sc_curchan; @@ -156,9 +157,7 @@ struct rt2661_softc { int dwelltime; struct rt2661_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; struct rt2661_tx_radiotap_header sc_txtap; - int sc_txtap_len; }; int rt2661_attach(device_t, int); diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860.c index 138fbc0ba1..c5f161e3c1 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860.c @@ -18,10 +18,10 @@ */ #include -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: releng/11.1/sys/dev/ral/rt2860.c 306851 2016-10-08 16:39:21Z avos $"); /*- - * Ralink Technology RT2860/RT3090/RT3390/RT3562 chipset driver + * Ralink Technology RT2860/RT3090/RT3390/RT3562/RT5390/RT5392 chipset driver * http://www.ralinktech.com/ */ @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -121,10 +122,10 @@ static int rt2860_raw_xmit(struct ieee80211_node *, struct mbuf *, static int rt2860_tx_raw(struct rt2860_softc *, struct mbuf *, struct ieee80211_node *, const struct ieee80211_bpf_params *params); -static void rt2860_start(struct ifnet *); -static void rt2860_start_locked(struct ifnet *); +static int rt2860_transmit(struct ieee80211com *, struct mbuf *); +static void rt2860_start(struct rt2860_softc *); static void rt2860_watchdog(void *); -static int rt2860_ioctl(struct ifnet *, u_long, caddr_t); +static void rt2860_parent(struct ieee80211com *); static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t); static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t); static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t); @@ -137,12 +138,17 @@ static void rt2860_set_basicrates(struct rt2860_softc *, const struct ieee80211_rateset *); static void rt2860_scan_start(struct ieee80211com *); static void rt2860_scan_end(struct ieee80211com *); +static void rt2860_getradiocaps(struct ieee80211com *, int, int *, + struct ieee80211_channel[]); static void rt2860_set_channel(struct ieee80211com *); static void rt2860_select_chan_group(struct rt2860_softc *, int); static void rt2860_set_chan(struct rt2860_softc *, u_int); static void rt3090_set_chan(struct rt2860_softc *, u_int); +static void rt5390_set_chan(struct rt2860_softc *, u_int); static int rt3090_rf_init(struct rt2860_softc *); +static void rt5390_rf_init(struct rt2860_softc *); static void rt3090_rf_wakeup(struct rt2860_softc *); +static void rt5390_rf_wakeup(struct rt2860_softc *); static int rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t, uint8_t *); static void rt3090_rf_setup(struct rt2860_softc *); @@ -150,9 +156,9 @@ static void rt2860_set_leds(struct rt2860_softc *, uint16_t); static void rt2860_set_gp_timer(struct rt2860_softc *, int); static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *); static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *); -static void rt2860_update_promisc(struct ifnet *); -static void rt2860_updateslot(struct ifnet *); -static void rt2860_updateprot(struct ifnet *); +static void rt2860_update_promisc(struct ieee80211com *); +static void rt2860_updateslot(struct ieee80211com *); +static void rt2860_updateprot(struct rt2860_softc *); static int rt2860_updateedca(struct ieee80211com *); #ifdef HW_CRYPTO static int rt2860_set_key(struct ieee80211com *, struct ieee80211_node *, @@ -161,10 +167,11 @@ static void rt2860_delete_key(struct ieee80211com *, struct ieee80211_node *, struct ieee80211_key *); #endif static int8_t rt2860_rssi2dbm(struct rt2860_softc *, uint8_t, uint8_t); -static const char *rt2860_get_rf(uint8_t); +static const char *rt2860_get_rf(uint16_t); static int rt2860_read_eeprom(struct rt2860_softc *, uint8_t macaddr[IEEE80211_ADDR_LEN]); static int rt2860_bbp_init(struct rt2860_softc *); +static void rt5390_bbp_init(struct rt2860_softc *); static int rt2860_txrx_enable(struct rt2860_softc *); static void rt2860_init(void *); static void rt2860_init_locked(struct rt2860_softc *); @@ -193,6 +200,8 @@ static const struct { uint8_t val; } rt2860_def_bbp[] = { RT2860_DEF_BBP +}, rt5390_def_bbp[] = { + RT5390_DEF_BBP }; static const struct rfprog { @@ -211,35 +220,37 @@ struct { static const struct { uint8_t reg; uint8_t val; -} rt3090_def_rf[] = { +} rt3090_def_rf[] = { RT3070_DEF_RF +}, rt5390_def_rf[] = { + RT5390_DEF_RF +}, rt5392_def_rf[] = { + RT5392_DEF_RF }; +static const uint8_t rt2860_chan_2ghz[] = + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; +static const uint8_t rt2860_chan_5ghz[] = + { 36, 38, 40, 44, 46, 48, 52, 54, 56, 60, 62, 64, 100, 102, 104, + 108, 110, 112, 116, 118, 120, 124, 126, 128, 132, 134, 136, 140, + 149, 151, 153, 157, 159, 161, 165, 167, 169, 171, 173 }; + int rt2860_attach(device_t dev, int id) { struct rt2860_softc *sc = device_get_softc(dev); - struct ieee80211com *ic; - struct ifnet *ifp; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; int error, ntries, qid; - uint8_t bands; - uint8_t macaddr[IEEE80211_ADDR_LEN]; sc->sc_dev = dev; sc->sc_debug = 0; - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - return ENOMEM; - } - ic = ifp->if_l2com; - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); + mbufq_init(&sc->sc_snd, ifqmaxlen); /* wait for NIC to initialize */ for (ntries = 0; ntries < 100; ntries++) { @@ -262,13 +273,11 @@ rt2860_attach(device_t dev, int id) sc->sc_flags |= RT2860_ADVANCED_PS; /* retrieve RF rev. no and various other things from EEPROM */ - rt2860_read_eeprom(sc, macaddr); - if (bootverbose) { - device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), " - "RF %s (MIMO %dT%dR), address %6D\n", - sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev), - sc->ntxchains, sc->nrxchains, macaddr, ":"); - } + rt2860_read_eeprom(sc, ic->ic_macaddr); + device_printf(sc->sc_dev, "MAC/BBP RT%X (rev 0x%04X), " + "RF %s (MIMO %dT%dR), address %6D\n", + sc->mac_ver, sc->mac_rev, rt2860_get_rf(sc->rf_rev), + sc->ntxchains, sc->nrxchains, ic->ic_macaddr, ":"); /* * Allocate Tx (4 EDCAs + HCCA + Mgt) and Rx rings. @@ -295,17 +304,8 @@ rt2860_attach(device_t dev, int id) sc->mgtqid = (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) ? WME_AC_VO : 5; - ifp->if_softc = sc; - if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_init = rt2860_init; - ifp->if_ioctl = rt2860_ioctl; - ifp->if_start = rt2860_start; - IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); - ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; - IFQ_SET_READY(&ifp->if_snd); - - ic->ic_ifp = ifp; + ic->ic_softc = sc; + ic->ic_name = device_get_nameunit(dev); ic->ic_opmode = IEEE80211_M_STA; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ @@ -327,18 +327,15 @@ rt2860_attach(device_t dev, int id) | IEEE80211_C_WME /* 802.11e */ ; - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) - setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, NULL, &bands); + rt2860_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans, + ic->ic_channels); - ieee80211_ifattach(ic, macaddr); + ieee80211_ifattach(ic); ic->ic_wme.wme_update = rt2860_updateedca; ic->ic_scan_start = rt2860_scan_start; ic->ic_scan_end = rt2860_scan_end; + ic->ic_getradiocaps = rt2860_getradiocaps; ic->ic_set_channel = rt2860_set_channel; ic->ic_updateslot = rt2860_updateslot; ic->ic_update_promisc = rt2860_update_promisc; @@ -346,7 +343,8 @@ rt2860_attach(device_t dev, int id) sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = rt2860_node_free; ic->ic_newassoc = rt2860_newassoc; - + ic->ic_transmit = rt2860_transmit; + ic->ic_parent = rt2860_parent; ic->ic_vap_create = rt2860_vap_create; ic->ic_vap_delete = rt2860_vap_delete; @@ -370,7 +368,6 @@ fail3: rt2860_free_rx_ring(sc, &sc->rxq); fail2: while (--qid >= 0) rt2860_free_tx_ring(sc, &sc->txq[qid]); fail1: mtx_destroy(&sc->sc_mtx); - if_free(ifp); return error; } @@ -378,8 +375,7 @@ int rt2860_detach(void *xsc) { struct rt2860_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; int qid; RAL_LOCK(sc); @@ -387,14 +383,12 @@ rt2860_detach(void *xsc) RAL_UNLOCK(sc); ieee80211_ifdetach(ic); - + mbufq_drain(&sc->sc_snd); for (qid = 0; qid < 6; qid++) rt2860_free_tx_ring(sc, &sc->txq[qid]); rt2860_free_rx_ring(sc, &sc->rxq); rt2860_free_tx_pool(sc); - if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; @@ -420,9 +414,8 @@ void rt2860_resume(void *xsc) { struct rt2860_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) + if (sc->sc_ic.ic_nrunning > 0) rt2860_init(sc); } @@ -432,7 +425,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct ifnet *ifp = ic->ic_ifp; + struct rt2860_softc *sc = ic->ic_softc; struct rt2860_vap *rvp; struct ieee80211vap *vap; @@ -445,7 +438,7 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_MBSS: /* XXXRP: TBD */ if (!TAILQ_EMPTY(&ic->ic_vaps)) { - if_printf(ifp, "only 1 vap supported\n"); + device_printf(sc->sc_dev, "only 1 vap supported\n"); return NULL; } if (opmode == IEEE80211_M_STA) @@ -454,7 +447,8 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, case IEEE80211_M_WDS: if (TAILQ_EMPTY(&ic->ic_vaps) || ic->ic_opmode != IEEE80211_M_HOSTAP) { - if_printf(ifp, "wds only supported in ap mode\n"); + device_printf(sc->sc_dev, + "wds only supported in ap mode\n"); return NULL; } /* @@ -465,14 +459,12 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, flags &= ~IEEE80211_CLONE_BSSID; break; default: - if_printf(ifp, "unknown opmode %d\n", opmode); + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); return NULL; } - rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_NOWAIT | M_ZERO); - if (rvp == NULL) - return NULL; + rvp = malloc(sizeof(struct rt2860_vap), M_80211_VAP, M_WAITOK | M_ZERO); vap = &rvp->ral_vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); /* override state transition machine */ rvp->ral_newstate = vap->iv_newstate; @@ -486,7 +478,8 @@ rt2860_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, ieee80211_ratectl_init(vap); /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status, mac); if (TAILQ_FIRST(&ic->ic_vaps) == vap) ic->ic_opmode = opmode; return vap; @@ -525,7 +518,7 @@ rt2860_alloc_tx_ring(struct rt2860_softc *sc, struct rt2860_tx_ring *ring) BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 1, size, 0, NULL, NULL, &ring->desc_dmat); if (error != 0) { - device_printf(sc->sc_dev, "could not create desc DMA map\n"); + device_printf(sc->sc_dev, "could not create desc DMA tag\n"); goto fail; } @@ -818,7 +811,7 @@ rt2860_free_rx_ring(struct rt2860_softc *sc, struct rt2860_rx_ring *ring) static void rt2860_updatestats(struct rt2860_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; /* * In IBSS or HostAP modes (when the hardware sends beacons), the @@ -845,7 +838,7 @@ static void rt2860_newassoc(struct ieee80211_node *ni, int isnew) { struct ieee80211com *ic = ni->ni_ic; - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint8_t wcid; wcid = IEEE80211_AID(ni->ni_associd); @@ -864,7 +857,7 @@ static void rt2860_node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint8_t wcid; if (ni->ni_associd != 0) { @@ -907,12 +900,12 @@ rt2860_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, } #endif -int +static int rt2860_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { struct rt2860_vap *rvp = RT2860_VAP(vap); struct ieee80211com *ic = vap->iv_ic; - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint32_t tmp; int error; @@ -1090,7 +1083,6 @@ rt2860_intr_coherent(struct rt2860_softc *sc) static void rt2860_drain_stats_fifo(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; struct ieee80211_node *ni; uint32_t stat; int retrycnt; @@ -1126,7 +1118,8 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc) } else { ieee80211_ratectl_tx_complete(ni->ni_vap, ni, IEEE80211_RATECTL_TX_FAILURE, &retrycnt, NULL); - ifp->if_oerrors++; + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); } } } @@ -1134,7 +1127,6 @@ rt2860_drain_stats_fifo(struct rt2860_softc *sc) static void rt2860_tx_intr(struct rt2860_softc *sc, int qid) { - struct ifnet *ifp = sc->sc_ifp; struct rt2860_tx_ring *ring = &sc->txq[qid]; uint32_t hw; @@ -1148,19 +1140,11 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid) bus_dmamap_sync(sc->txwi_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->txwi_dmat, data->map); - if (data->m->m_flags & M_TXCB) { - ieee80211_process_callback(data->ni, data->m, - 0); - } - m_freem(data->m); - ieee80211_free_node(data->ni); - data->m = NULL; + ieee80211_tx_complete(data->ni, data->m, 0); data->ni = NULL; - + data->m = NULL; SLIST_INSERT_HEAD(&sc->data_pool, data, next); ring->data[ring->next] = NULL; - - ifp->if_opackets++; } ring->queued--; ring->next = (ring->next + 1) % RT2860_TX_RING_COUNT; @@ -1169,8 +1153,7 @@ rt2860_tx_intr(struct rt2860_softc *sc, int qid) sc->sc_tx_timer = 0; if (ring->queued < RT2860_TX_RING_COUNT) sc->qfullmsk &= ~(1 << qid); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2860_start_locked(ifp); + rt2860_start(sc); } /* @@ -1195,8 +1178,7 @@ static void rt2860_rx_intr(struct rt2860_softc *sc) { struct rt2860_rx_radiotap_header *tap; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *m, *m1; @@ -1223,7 +1205,7 @@ rt2860_rx_intr(struct rt2860_softc *sc) if (__predict_false(rxd->flags & htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1232,14 +1214,14 @@ rt2860_rx_intr(struct rt2860_softc *sc) /* report MIC failures to net80211 for TKIP */ ic->ic_stats.is_rx_locmicfail++; ieee80211_michael_mic_failure(ic, 0/* XXX */); - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } #endif m1 = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m1 == NULL)) { - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1263,7 +1245,7 @@ rt2860_rx_intr(struct rt2860_softc *sc) } /* physical address may have changed */ rxd->sdp0 = htole32(physaddr); - ifp->if_ierrors++; + counter_u64_add(ic->ic_ierrors, 1); goto skip; } @@ -1278,15 +1260,14 @@ rt2860_rx_intr(struct rt2860_softc *sc) rxwi = mtod(m, struct rt2860_rxwi *); /* finalize mbuf */ - m->m_pkthdr.rcvif = ifp; m->m_data = (caddr_t)(rxwi + 1); m->m_pkthdr.len = m->m_len = le16toh(rxwi->len) & 0xfff; wh = mtod(m, struct ieee80211_frame *); #ifdef HW_CRYPTO - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { /* frame is decrypted by hardware */ - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; + wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED; } #endif @@ -1388,7 +1369,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc) #endif /* check if protection mode has changed */ if ((sc->sc_ic_flags ^ ic->ic_flags) & IEEE80211_F_USEPROT) { - rt2860_updateprot(ic); + rt2860_updateprot(sc); sc->sc_ic_flags = ic->ic_flags; } #endif @@ -1397,7 +1378,7 @@ rt2860_tbtt_intr(struct rt2860_softc *sc) static void rt2860_gp_intr(struct rt2860_softc *sc) { - struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTFN(2, ("GP timeout state=%d\n", vap->iv_state)); @@ -1473,8 +1454,7 @@ rt2860_intr(void *arg) static int rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct rt2860_tx_ring *ring; struct rt2860_tx_data *data; @@ -1496,7 +1476,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) wh = mtod(m, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { k = ieee80211_crypto_encap(ni, m); if (k == NULL) { m_freem(m); @@ -1532,7 +1512,7 @@ rt2860_tx(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni) tid = 0; } ring = &sc->txq[qid]; - ridx = ic->ic_rt->rateCodeToIndex[rate]; + ridx = ieee80211_legacy_rate_lookup(ic->ic_rt, rate); /* get MCS code from rate index */ mcs = rt2860_rates[ridx].mcs; @@ -1718,17 +1698,15 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; int error; RAL_LOCK(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RT2860_RUNNING)) { RAL_UNLOCK(sc); m_freem(m); - ieee80211_free_node(ni); return ENETDOWN; } if (params == NULL) { @@ -1744,11 +1722,6 @@ rt2860_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, */ error = rt2860_tx_raw(sc, m, ni, params); } - if (error != 0) { - /* NB: m is reclaimed on tx failure */ - ieee80211_free_node(ni); - ifp->if_oerrors++; - } sc->sc_tx_timer = 5; RAL_UNLOCK(sc); return error; @@ -1758,8 +1731,7 @@ static int rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = ni->ni_vap; struct rt2860_tx_ring *ring; struct rt2860_tx_data *data; @@ -1783,7 +1755,8 @@ rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, /* Choose a TX rate index. */ rate = params->ibp_rate0; - ridx = ic->ic_rt->rateCodeToIndex[rate]; + ridx = ieee80211_legacy_rate_lookup(ic->ic_rt, + rate & IEEE80211_RATE_VAL); if (ridx == (uint8_t)-1) { /* XXX fall back to mcast/mgmt rate? */ m_freem(m); @@ -1965,41 +1938,46 @@ rt2860_tx_raw(struct rt2860_softc *sc, struct mbuf *m, return 0; } -static void -rt2860_start(struct ifnet *ifp) +static int +rt2860_transmit(struct ieee80211com *ic, struct mbuf *m) { - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; + int error; RAL_LOCK(sc); - rt2860_start_locked(ifp); + if ((sc->sc_flags & RT2860_RUNNING) == 0) { + RAL_UNLOCK(sc); + return (ENXIO); + } + error = mbufq_enqueue(&sc->sc_snd, m); + if (error) { + RAL_UNLOCK(sc); + return (error); + } + rt2860_start(sc); RAL_UNLOCK(sc); + + return (0); } static void -rt2860_start_locked(struct ifnet *ifp) +rt2860_start(struct rt2860_softc *sc) { - struct rt2860_softc *sc = ifp->if_softc; struct ieee80211_node *ni; struct mbuf *m; RAL_LOCK_ASSERT(sc); - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || - (ifp->if_drv_flags & IFF_DRV_OACTIVE)) + if ((sc->sc_flags & RT2860_RUNNING) == 0) return; - for (;;) { - if (SLIST_EMPTY(&sc->data_pool) || sc->qfullmsk != 0) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; + while (!SLIST_EMPTY(&sc->data_pool) && sc->qfullmsk == 0 && + (m = mbufq_dequeue(&sc->sc_snd)) != NULL) { ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; if (rt2860_tx(sc, m, ni) != 0) { + if_inc_counter(ni->ni_vap->iv_ifp, + IFCOUNTER_OERRORS, 1); ieee80211_free_node(ni); - ifp->if_oerrors++; continue; } sc->sc_tx_timer = 5; @@ -2010,61 +1988,42 @@ static void rt2860_watchdog(void *arg) { struct rt2860_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; RAL_LOCK_ASSERT(sc); - KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + KASSERT(sc->sc_flags & RT2860_RUNNING, ("not running")); if (sc->sc_invalid) /* card ejected */ return; if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); + device_printf(sc->sc_dev, "device timeout\n"); rt2860_stop_locked(sc); rt2860_init_locked(sc); - ifp->if_oerrors++; + counter_u64_add(sc->sc_ic.ic_oerrors, 1); return; } callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); } -static int -rt2860_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +static void +rt2860_parent(struct ieee80211com *ic) { - struct rt2860_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *)data; - int error = 0, startall = 0; + struct rt2860_softc *sc = ic->ic_softc; + int startall = 0; - switch (cmd) { - case SIOCSIFFLAGS: - RAL_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - rt2860_init_locked(sc); - startall = 1; - } else - rt2860_update_promisc(ifp); - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2860_stop_locked(sc); - } - RAL_UNLOCK(sc); - if (startall) - ieee80211_start_all(ic); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCSIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; + RAL_LOCK(sc); + if (ic->ic_nrunning> 0) { + if (!(sc->sc_flags & RT2860_RUNNING)) { + rt2860_init_locked(sc); + startall = 1; + } else + rt2860_update_promisc(ic); + } else if (sc->sc_flags & RT2860_RUNNING) + rt2860_stop_locked(sc); + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); } /* @@ -2084,7 +2043,7 @@ rt2860_mcu_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val) } if (ntries == 100) { device_printf(sc->sc_dev, - "could not write to BBP through MCU\n"); + "could not write to BBP through MCU\n"); return; } @@ -2287,8 +2246,7 @@ rt2860_enable_mrr(struct rt2860_softc *sc) static void rt2860_set_txpreamble(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RAL_READ(sc, RT2860_AUTO_RSP_CFG); @@ -2302,9 +2260,7 @@ void rt2860_set_basicrates(struct rt2860_softc *sc, const struct ieee80211_rateset *rs) { -#define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t mask = 0; uint8_t rate; int i; @@ -2315,18 +2271,17 @@ rt2860_set_basicrates(struct rt2860_softc *sc, if (!(rate & IEEE80211_RATE_BASIC)) continue; - mask |= 1 << ic->ic_rt->rateCodeToIndex[RV(rate)]; + mask |= 1 << ieee80211_legacy_rate_lookup(ic->ic_rt, + IEEE80211_RV(rate)); } RAL_WRITE(sc, RT2860_LEGACY_BASIC_RATE, mask); -#undef RV } static void rt2860_scan_start(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); @@ -2339,8 +2294,7 @@ rt2860_scan_start(struct ieee80211com *ic) static void rt2860_scan_end(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); if (vap->iv_state == IEEE80211_S_RUN) { @@ -2349,11 +2303,30 @@ rt2860_scan_end(struct ieee80211com *ic) } } +static void +rt2860_getradiocaps(struct ieee80211com *ic, int maxchans, int *nchans, + struct ieee80211_channel chans[]) +{ + struct rt2860_softc *sc = ic->ic_softc; + uint8_t bands[IEEE80211_MODE_BYTES]; + + memset(bands, 0, sizeof(bands)); + setbit(bands, IEEE80211_MODE_11B); + setbit(bands, IEEE80211_MODE_11G); + ieee80211_add_channel_list_2ghz(chans, maxchans, nchans, + rt2860_chan_2ghz, nitems(rt2860_chan_2ghz), bands, 0); + + if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850) { + setbit(bands, IEEE80211_MODE_11A); + ieee80211_add_channel_list_5ghz(chans, maxchans, nchans, + rt2860_chan_5ghz, nitems(rt2860_chan_5ghz), bands, 0); + } +} + static void rt2860_set_channel(struct ieee80211com *ic) { - struct ifnet *ifp = ic->ic_ifp; - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; RAL_LOCK(sc); rt2860_switch_chan(sc, ic->ic_curchan); @@ -2564,10 +2537,110 @@ rt3090_set_chan(struct rt2860_softc *sc, u_int chan) rt3090_rf_write(sc, 7, rf | RT3070_TUNE); } +static void +rt5390_set_chan(struct rt2860_softc *sc, u_int chan) +{ + uint8_t h20mhz, rf, tmp; + int8_t txpow1, txpow2; + int i; + + /* RT5390 is 2GHz only */ + KASSERT(chan >= 1 && chan <= 14, ("chan %d not support", chan)); + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++); + + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + + rt3090_rf_write(sc, 8, rt3090_freqs[i].n); + rt3090_rf_write(sc, 9, rt3090_freqs[i].k & 0x0f); + rf = rt3090_rf_read(sc, 11); + rf = (rf & ~0x03) | (rt3090_freqs[i].r & 0x03); + rt3090_rf_write(sc, 11, rf); + + rf = rt3090_rf_read(sc, 49); + rf = (rf & ~0x3f) | (txpow1 & 0x3f); + /* the valid range of the RF R49 is 0x00~0x27 */ + if ((rf & 0x3f) > 0x27) + rf = (rf & ~0x3f) | 0x27; + rt3090_rf_write(sc, 49, rf); + if (sc->mac_ver == 0x5392) { + rf = rt3090_rf_read(sc, 50); + rf = (rf & ~0x3f) | (txpow2 & 0x3f); + /* the valid range of the RF R50 is 0x00~0x27 */ + if ((rf & 0x3f) > 0x27) + rf = (rf & ~0x3f) | 0x27; + rt3090_rf_write(sc, 50, rf); + } + + rf = rt3090_rf_read(sc, 1); + rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD; + if (sc->mac_ver == 0x5392) + rf |= RT3070_RX1_PD | RT3070_TX1_PD; + rt3090_rf_write(sc, 1, rf); + + rf = rt3090_rf_read(sc, 2); + rt3090_rf_write(sc, 2, rf | RT3593_RESCAL); + DELAY(1000); + rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL); + + rf = rt3090_rf_read(sc, 17); + tmp = rf; + rf = (rf & ~0x7f) | (sc->freq & 0x7f); + rf = MIN(rf, 0x5f); + if (tmp != rf) + rt2860_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf, 0); + + if (sc->mac_ver == 0x5390) { + if (chan <= 4) + rf = 0x73; + else if (chan >= 5 && chan <= 6) + rf = 0x63; + else if (chan >= 7 && chan <= 10) + rf = 0x53; + else + rf = 43; + rt3090_rf_write(sc, 55, rf); + + if (chan == 1) + rf = 0x0c; + else if (chan == 2) + rf = 0x0b; + else if (chan == 3) + rf = 0x0a; + else if (chan >= 4 && chan <= 6) + rf = 0x09; + else if (chan >= 7 && chan <= 12) + rf = 0x08; + else if (chan == 13) + rf = 0x07; + else + rf = 0x06; + rt3090_rf_write(sc, 59, rf); + } + + /* Tx/Rx h20M */ + h20mhz = (sc->rf24_20mhz & 0x20) >> 5; + rf = rt3090_rf_read(sc, 30); + rf = (rf & ~0x06) | (h20mhz << 1) | (h20mhz << 2); + rt3090_rf_write(sc, 30, rf); + + /* Rx BB filter VCM */ + rf = rt3090_rf_read(sc, 30); + rf = (rf & ~0x18) | 0x10; + rt3090_rf_write(sc, 30, rf); + + /* Initiate VCO calibration. */ + rf = rt3090_rf_read(sc, 3); + rf |= RT3593_VCOCAL; + rt3090_rf_write(sc, 3, rf); +} + static int rt3090_rf_init(struct rt2860_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) uint32_t tmp; uint8_t rf, bbp; int i; @@ -2591,7 +2664,7 @@ rt3090_rf_init(struct rt2860_softc *sc) RAL_WRITE(sc, RT3070_GPIO_SWITCH, tmp & ~0x20); /* initialize RF registers to default value */ - for (i = 0; i < N(rt3090_def_rf); i++) { + for (i = 0; i < nitems(rt3090_def_rf); i++) { rt3090_rf_write(sc, rt3090_def_rf[i].reg, rt3090_def_rf[i].val); } @@ -2670,11 +2743,79 @@ rt3090_rf_init(struct rt2860_softc *sc) rf = rt3090_rf_read(sc, 21); rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2); - return 0; -#undef N + return (0); } -void +static void +rt5390_rf_init(struct rt2860_softc *sc) +{ + uint8_t rf, bbp; + int i; + + rf = rt3090_rf_read(sc, 2); + /* Toggle RF R2 bit 7. */ + rt3090_rf_write(sc, 2, rf | RT3593_RESCAL); + DELAY(1000); + rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL); + + /* Initialize RF registers to default value. */ + if (sc->mac_ver == 0x5392) { + for (i = 0; i < nitems(rt5392_def_rf); i++) { + rt3090_rf_write(sc, rt5392_def_rf[i].reg, + rt5392_def_rf[i].val); + } + } else { + for (i = 0; i < nitems(rt5390_def_rf); i++) { + rt3090_rf_write(sc, rt5390_def_rf[i].reg, + rt5390_def_rf[i].val); + } + } + + sc->rf24_20mhz = 0x1f; + sc->rf24_40mhz = 0x2f; + + if (sc->mac_rev < 0x0211) + rt3090_rf_write(sc, 27, 0x03); + + /* Set led open drain enable. */ + RAL_WRITE(sc, RT3070_OPT_14, RAL_READ(sc, RT3070_OPT_14) | 1); + + RAL_WRITE(sc, RT2860_TX_SW_CFG1, 0); + RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0); + + if (sc->mac_ver == 0x5390) + rt3090_set_rx_antenna(sc, 0); + + /* Patch RSSI inaccurate issue. */ + rt2860_mcu_bbp_write(sc, 79, 0x13); + rt2860_mcu_bbp_write(sc, 80, 0x05); + rt2860_mcu_bbp_write(sc, 81, 0x33); + + /* Enable DC filter. */ + if (sc->mac_rev >= 0x0211) + rt2860_mcu_bbp_write(sc, 103, 0xc0); + + bbp = rt2860_mcu_bbp_read(sc, 138); + if (sc->ntxchains == 1) + bbp |= 0x20; /* Turn off DAC1. */ + if (sc->nrxchains == 1) + bbp &= ~0x02; /* Turn off ADC1. */ + rt2860_mcu_bbp_write(sc, 138, bbp); + + /* Enable RX LO1 and LO2. */ + rt3090_rf_write(sc, 38, rt3090_rf_read(sc, 38) & ~RT5390_RX_LO1); + rt3090_rf_write(sc, 39, rt3090_rf_read(sc, 39) & ~RT5390_RX_LO2); + + /* Avoid data lost and CRC error. */ + rt2860_mcu_bbp_write(sc, 4, + rt2860_mcu_bbp_read(sc, 4) | RT5390_MAC_IF_CTRL); + + rf = rt3090_rf_read(sc, 30); + rf = (rf & ~0x18) | 0x10; + rt3090_rf_write(sc, 30, rf); +} + +static void rt3090_rf_wakeup(struct rt2860_softc *sc) { uint32_t tmp; @@ -2740,7 +2881,43 @@ rt3090_rf_wakeup(struct rt2860_softc *sc) } } -int +static void +rt5390_rf_wakeup(struct rt2860_softc *sc) +{ + uint32_t tmp; + uint8_t rf; + + rf = rt3090_rf_read(sc, 1); + rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | + RT3070_TX0_PD; + if (sc->mac_ver == 0x5392) + rf |= RT3070_RX1_PD | RT3070_TX1_PD; + rt3090_rf_write(sc, 1, rf); + + rf = rt3090_rf_read(sc, 6); + rf |= RT3593_VCO_IC | RT3593_VCOCAL; + if (sc->mac_ver == 0x5390) + rf &= ~RT3593_VCO_IC; + rt3090_rf_write(sc, 6, rf); + + rt3090_rf_write(sc, 2, rt3090_rf_read(sc, 2) | RT3593_RESCAL); + + rf = rt3090_rf_read(sc, 22); + rf = (rf & ~0xe0) | 0x20; + rt3090_rf_write(sc, 22, rf); + + rt3090_rf_write(sc, 42, rt3090_rf_read(sc, 42) | RT5390_RX_CTB); + rt3090_rf_write(sc, 20, rt3090_rf_read(sc, 20) & ~0x77); + rt3090_rf_write(sc, 3, rt3090_rf_read(sc, 3) | RT3593_VCOCAL); + + if (sc->patch_dac && sc->mac_rev < 0x0211) { + tmp = RAL_READ(sc, RT3070_LDO_CFG0); + tmp = (tmp & ~0x1f000000) | 0x0d000000; + RAL_WRITE(sc, RT3070_LDO_CFG0, tmp); + } +} + +static int rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, uint8_t *val) { @@ -2769,7 +2946,7 @@ rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, break; } if (ntries == 100) - return ETIMEDOUT; + return (ETIMEDOUT); /* set power and frequency of stopband test tone */ rt2860_mcu_bbp_write(sc, 24, 0x06); @@ -2802,7 +2979,7 @@ rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, rf22 = rt3090_rf_read(sc, 22); rt3090_rf_write(sc, 22, rf22 & ~RT3070_BB_LOOPBACK); - return 0; + return (0); } static void @@ -2828,10 +3005,12 @@ rt3090_rf_setup(struct rt2860_softc *sc) RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0); /* initialize RF registers from ROM */ - for (i = 0; i < 10; i++) { - if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff) - continue; - rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val); + if (sc->mac_ver < 0x5390) { + for (i = 0; i < 10; i++) { + if (sc->rf[i].reg == 0 || sc->rf[i].reg == 0xff) + continue; + rt3090_rf_write(sc, sc->rf[i].reg, sc->rf[i].val); + } } } @@ -2887,23 +3066,21 @@ rt2860_set_macaddr(struct rt2860_softc *sc, const uint8_t *addr) } static void -rt2860_updateslot(struct ifnet *ifp) +rt2860_updateslot(struct ieee80211com *ic) { - struct rt2860_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct rt2860_softc *sc = ic->ic_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2860_BKOFF_SLOT_CFG); tmp &= ~0xff; - tmp |= (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; + tmp |= IEEE80211_GET_SLOTTIME(ic); RAL_WRITE(sc, RT2860_BKOFF_SLOT_CFG, tmp); } static void -rt2860_updateprot(struct ifnet *ifp) +rt2860_updateprot(struct rt2860_softc *sc) { - struct rt2860_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; tmp = RT2860_RTSTH_EN | RT2860_PROT_NAV_SHORT | RT2860_TXOP_ALLOW_ALL; @@ -2925,14 +3102,14 @@ rt2860_updateprot(struct ifnet *ifp) } static void -rt2860_update_promisc(struct ifnet *ifp) +rt2860_update_promisc(struct ieee80211com *ic) { - struct rt2860_softc *sc = ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2860_RX_FILTR_CFG); tmp &= ~RT2860_DROP_NOT_MYBSS; - if (!(ifp->if_flags & IFF_PROMISC)) + if (ic->ic_promisc == 0) tmp |= RT2860_DROP_NOT_MYBSS; RAL_WRITE(sc, RT2860_RX_FILTR_CFG, tmp); } @@ -2940,7 +3117,7 @@ rt2860_update_promisc(struct ifnet *ifp) static int rt2860_updateedca(struct ieee80211com *ic) { - struct rt2860_softc *sc = ic->ic_ifp->if_softc; + struct rt2860_softc *sc = ic->ic_softc; const struct wmeParams *wmep; int aci; @@ -3112,8 +3289,7 @@ rt2860_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, static int8_t rt2860_rssi2dbm(struct rt2860_softc *sc, uint8_t rssi, uint8_t rxchain) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_channel *c = ic->ic_curchan; int delta; @@ -3156,7 +3332,7 @@ b4inc(uint32_t b32, int8_t delta) } static const char * -rt2860_get_rf(uint8_t rev) +rt2860_get_rf(uint16_t rev) { switch (rev) { case RT2860_RF_2820: return "RT2820"; @@ -3170,6 +3346,8 @@ rt2860_get_rf(uint8_t rev) case RT3070_RF_3052: return "RT3052"; case RT3070_RF_3320: return "RT3320"; case RT3070_RF_3053: return "RT3053"; + case RT5390_RF_5360: return "RT5360"; + case RT5390_RF_5390: return "RT5390"; default: return "unknown"; } } @@ -3191,9 +3369,11 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) sc->sc_srom_read = rt3090_efuse_read_2; } +#ifdef RAL_DEBUG /* read EEPROM version */ val = rt2860_srom_read(sc, RT2860_EEPROM_VERSION); - DPRINTF(("EEPROM rev=%d, FAE=%d\n", val & 0xff, val >> 8)); + DPRINTF(("EEPROM rev=%d, FAE=%d\n", val >> 8, val & 0xff)); +#endif /* read MAC address */ val = rt2860_srom_read(sc, RT2860_EEPROM_MAC01); @@ -3206,9 +3386,11 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) macaddr[4] = val & 0xff; macaddr[5] = val >> 8; +#ifdef RAL_DEBUG /* read country code */ val = rt2860_srom_read(sc, RT2860_EEPROM_COUNTRY); DPRINTF(("EEPROM region code=0x%04x\n", val)); +#endif /* read vendor BBP settings */ for (i = 0; i < 8; i++) { @@ -3250,29 +3432,12 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) /* read RF information */ val = rt2860_srom_read(sc, RT2860_EEPROM_ANTENNA); - if (val == 0xffff) { - DPRINTF(("invalid EEPROM antenna info, using default\n")); - if (sc->mac_ver == 0x3593) { - /* default to RF3053 3T3R */ - sc->rf_rev = RT3070_RF_3053; - sc->ntxchains = 3; - sc->nrxchains = 3; - } else if (sc->mac_ver >= 0x3071) { - /* default to RF3020 1T1R */ - sc->rf_rev = RT3070_RF_3020; - sc->ntxchains = 1; - sc->nrxchains = 1; - } else { - /* default to RF2820 1T2R */ - sc->rf_rev = RT2860_RF_2820; - sc->ntxchains = 1; - sc->nrxchains = 2; - } - } else { + if (sc->mac_ver >= 0x5390) + sc->rf_rev = rt2860_srom_read(sc, RT2860_EEPROM_CHIPID); + else sc->rf_rev = (val >> 8) & 0xf; - sc->ntxchains = (val >> 4) & 0xf; - sc->nrxchains = val & 0xf; - } + sc->ntxchains = (val >> 4) & 0xf; + sc->nrxchains = val & 0xf; DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n", sc->rf_rev, sc->ntxchains, sc->nrxchains)); @@ -3286,7 +3451,7 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) sc->ext_5ghz_lna = (val >> 3) & 1; sc->ext_2ghz_lna = (val >> 2) & 1; /* check if RF supports automatic Tx access gain control */ - sc->calib_2ghz = sc->calib_5ghz = 0; /* XXX (val >> 1) & 1 */; + sc->calib_2ghz = sc->calib_5ghz = 0; /* XXX (val >> 1) & 1 */ /* check if we have a hardware radio switch */ sc->rfswitch = val & 1; } @@ -3309,17 +3474,23 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) sc->txpow1[i + 0] = (int8_t)(val & 0xff); sc->txpow1[i + 1] = (int8_t)(val >> 8); - val = rt2860_srom_read(sc, - RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2); - sc->txpow2[i + 0] = (int8_t)(val & 0xff); - sc->txpow2[i + 1] = (int8_t)(val >> 8); + if (sc->mac_ver != 0x5390) { + val = rt2860_srom_read(sc, + RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2); + sc->txpow2[i + 0] = (int8_t)(val & 0xff); + sc->txpow2[i + 1] = (int8_t)(val >> 8); + } } /* fix broken Tx power entries */ for (i = 0; i < 14; i++) { - if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) + if (sc->txpow1[i] < 0 || + sc->txpow1[i] > ((sc->mac_ver >= 0x5390) ? 39 : 31)) sc->txpow1[i] = 5; - if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) - sc->txpow2[i] = 5; + if (sc->mac_ver != 0x5390) { + if (sc->txpow2[i] < 0 || + sc->txpow2[i] > ((sc->mac_ver == 0x5392) ? 39 : 31)) + sc->txpow2[i] = 5; + } DPRINTF(("chan %d: power1=%d, power2=%d\n", rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i])); } @@ -3487,10 +3658,9 @@ rt2860_read_eeprom(struct rt2860_softc *sc, uint8_t macaddr[IEEE80211_ADDR_LEN]) return 0; } -int +static int rt2860_bbp_init(struct rt2860_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) int i, ntries; /* wait for BBP to wake up */ @@ -3502,13 +3672,17 @@ rt2860_bbp_init(struct rt2860_softc *sc) if (ntries == 20) { device_printf(sc->sc_dev, "timeout waiting for BBP to wake up\n"); - return ETIMEDOUT; + return (ETIMEDOUT); } /* initialize BBP registers to default values */ - for (i = 0; i < N(rt2860_def_bbp); i++) { - rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg, - rt2860_def_bbp[i].val); + if (sc->mac_ver >= 0x5390) + rt5390_bbp_init(sc); + else { + for (i = 0; i < nitems(rt2860_def_bbp); i++) { + rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg, + rt2860_def_bbp[i].val); + } } /* fix BBP84 for RT2860E */ @@ -3525,14 +3699,50 @@ rt2860_bbp_init(struct rt2860_softc *sc) } return 0; -#undef N +} + +static void +rt5390_bbp_init(struct rt2860_softc *sc) +{ + uint8_t bbp; + int i; + + /* Apply maximum likelihood detection for 2 stream case. */ + if (sc->nrxchains > 1) { + bbp = rt2860_mcu_bbp_read(sc, 105); + rt2860_mcu_bbp_write(sc, 105, bbp | RT5390_MLD); + } + + /* Avoid data lost and CRC error. */ + bbp = rt2860_mcu_bbp_read(sc, 4); + rt2860_mcu_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL); + + for (i = 0; i < nitems(rt5390_def_bbp); i++) { + rt2860_mcu_bbp_write(sc, rt5390_def_bbp[i].reg, + rt5390_def_bbp[i].val); + } + + if (sc->mac_ver == 0x5392) { + rt2860_mcu_bbp_write(sc, 84, 0x9a); + rt2860_mcu_bbp_write(sc, 95, 0x9a); + rt2860_mcu_bbp_write(sc, 98, 0x12); + rt2860_mcu_bbp_write(sc, 106, 0x05); + rt2860_mcu_bbp_write(sc, 134, 0xd0); + rt2860_mcu_bbp_write(sc, 135, 0xf6); + } + + bbp = rt2860_mcu_bbp_read(sc, 152); + rt2860_mcu_bbp_write(sc, 152, bbp | 0x80); + + /* Disable hardware antenna diversity. */ + if (sc->mac_ver == 0x5390) + rt2860_mcu_bbp_write(sc, 154, 0); } static int rt2860_txrx_enable(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; uint32_t tmp; int ntries; @@ -3578,23 +3788,21 @@ static void rt2860_init(void *arg) { struct rt2860_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; RAL_LOCK(sc); rt2860_init_locked(sc); RAL_UNLOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RT2860_RUNNING) ieee80211_start_all(ic); } static void rt2860_init_locked(struct rt2860_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; uint8_t bbp1, bbp3; int i, qid, ridx, ntries, error; @@ -3616,9 +3824,16 @@ rt2860_init_locked(struct rt2860_softc *sc) /* disable DMA */ tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); - tmp &= 0xff0; + tmp &= ~(RT2860_RX_DMA_BUSY | RT2860_RX_DMA_EN | RT2860_TX_DMA_BUSY | + RT2860_TX_DMA_EN); + tmp |= RT2860_TX_WB_DDONE; RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); + /* reset DMA indexes */ + RAL_WRITE(sc, RT2860_WPDMA_RST_IDX, RT2860_RST_DRX_IDX0 | + RT2860_RST_DTX_IDX5 | RT2860_RST_DTX_IDX4 | RT2860_RST_DTX_IDX3 | + RT2860_RST_DTX_IDX2 | RT2860_RST_DTX_IDX1 | RT2860_RST_DTX_IDX0); + /* PBF hardware reset */ RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f); RAL_BARRIER_WRITE(sc); @@ -3630,7 +3845,7 @@ rt2860_init_locked(struct rt2860_softc *sc) return; } - rt2860_set_macaddr(sc, IF_LLADDR(ifp)); + rt2860_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr); /* init Tx power for all Tx rates (from EEPROM) */ for (ridx = 0; ridx < 5; ridx++) { @@ -3650,7 +3865,9 @@ rt2860_init_locked(struct rt2860_softc *sc) rt2860_stop_locked(sc); return; } - tmp &= 0xff0; + tmp &= ~(RT2860_RX_DMA_BUSY | RT2860_RX_DMA_EN | RT2860_TX_DMA_BUSY | + RT2860_TX_DMA_EN); + tmp |= RT2860_TX_WB_DDONE; RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); /* reset Rx ring and all 6 Tx rings */ @@ -3667,9 +3884,11 @@ rt2860_init_locked(struct rt2860_softc *sc) RAL_BARRIER_WRITE(sc); RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0); - for (i = 0; i < N(rt2860_def_mac); i++) + for (i = 0; i < nitems(rt2860_def_mac); i++) RAL_WRITE(sc, rt2860_def_mac[i].reg, rt2860_def_mac[i].val); - if (sc->mac_ver >= 0x3071) { + if (sc->mac_ver >= 0x5390) + RAL_WRITE(sc, RT2860_TX_SW_CFG0, 0x00000404); + else if (sc->mac_ver >= 0x3071) { /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ RAL_WRITE(sc, RT2860_TX_SW_CFG0, 4 << RT2860_DLY_PAPE_EN_SHIFT); @@ -3748,7 +3967,9 @@ rt2860_init_locked(struct rt2860_softc *sc) rt2860_stop_locked(sc); return; } - tmp &= 0xff0; + tmp &= ~(RT2860_RX_DMA_BUSY | RT2860_RX_DMA_EN | RT2860_TX_DMA_BUSY | + RT2860_TX_DMA_EN); + tmp |= RT2860_TX_WB_DDONE; RAL_WRITE(sc, RT2860_WPDMA_GLO_CFG, tmp); /* disable interrupts mitigation */ @@ -3764,7 +3985,8 @@ rt2860_init_locked(struct rt2860_softc *sc) /* select Main antenna for 1T1R devices */ if (sc->rf_rev == RT3070_RF_2020 || sc->rf_rev == RT3070_RF_3020 || - sc->rf_rev == RT3070_RF_3320) + sc->rf_rev == RT3070_RF_3320 || + sc->mac_ver == 0x5390) rt3090_set_rx_antenna(sc, 0); /* send LEDs operating mode to microcontroller */ @@ -3772,13 +3994,21 @@ rt2860_init_locked(struct rt2860_softc *sc) rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1], 0); rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2], 0); - if (sc->mac_ver >= 0x3071) - rt3090_rf_init(sc); + if (sc->mac_ver >= 0x5390) + rt5390_rf_init(sc); + else if (sc->mac_ver >= 0x3071) { + if ((error = rt3090_rf_init(sc)) != 0) { + rt2860_stop_locked(sc); + return; + } + } rt2860_mcu_cmd(sc, RT2860_MCU_CMD_SLEEP, 0x02ff, 1); rt2860_mcu_cmd(sc, RT2860_MCU_CMD_WAKEUP, 0, 1); - if (sc->mac_ver >= 0x3071) + if (sc->mac_ver >= 0x5390) + rt5390_rf_wakeup(sc); + else if (sc->mac_ver >= 0x3071) rt3090_rf_wakeup(sc); /* disable non-existing Rx chains */ @@ -3816,7 +4046,7 @@ rt2860_init_locked(struct rt2860_softc *sc) RAL_WRITE(sc, RT2860_TX_RTS_CFG, tmp); /* setup initial protection mode */ - rt2860_updateprot(ifp); + rt2860_updateprot(sc); /* turn radio LED on */ rt2860_set_leds(sc, RT2860_LED_RADIO); @@ -3835,11 +4065,9 @@ rt2860_init_locked(struct rt2860_softc *sc) if (sc->sc_flags & RT2860_ADVANCED_PS) rt2860_mcu_cmd(sc, RT2860_MCU_CMD_PSLEVEL, sc->pslevel, 0); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= RT2860_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2860_watchdog, sc); -#undef N } static void @@ -3855,16 +4083,15 @@ rt2860_stop(void *arg) static void rt2860_stop_locked(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; int qid; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if (sc->sc_flags & RT2860_RUNNING) rt2860_set_leds(sc, 0); /* turn all LEDs off */ callout_stop(&sc->watchdog_ch); sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~RT2860_RUNNING; /* disable interrupts */ RAL_WRITE(sc, RT2860_INT_MASK, 0); @@ -3990,30 +4217,41 @@ rt3090_set_rx_antenna(struct rt2860_softc *sc, int aux) uint32_t tmp; if (aux) { - tmp = RAL_READ(sc, RT2860_PCI_EECTRL); - RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C); - tmp = RAL_READ(sc, RT2860_GPIO_CTRL); - RAL_WRITE(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08); + if (sc->mac_ver == 0x5390) { + rt2860_mcu_bbp_write(sc, 152, + rt2860_mcu_bbp_read(sc, 152) & ~0x80); + } else { + tmp = RAL_READ(sc, RT2860_PCI_EECTRL); + RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp & ~RT2860_C); + tmp = RAL_READ(sc, RT2860_GPIO_CTRL); + RAL_WRITE(sc, RT2860_GPIO_CTRL, (tmp & ~0x0808) | 0x08); + } } else { - tmp = RAL_READ(sc, RT2860_PCI_EECTRL); - RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp | RT2860_C); - tmp = RAL_READ(sc, RT2860_GPIO_CTRL); - RAL_WRITE(sc, RT2860_GPIO_CTRL, tmp & ~0x0808); + if (sc->mac_ver == 0x5390) { + rt2860_mcu_bbp_write(sc, 152, + rt2860_mcu_bbp_read(sc, 152) | 0x80); + } else { + tmp = RAL_READ(sc, RT2860_PCI_EECTRL); + RAL_WRITE(sc, RT2860_PCI_EECTRL, tmp | RT2860_C); + tmp = RAL_READ(sc, RT2860_GPIO_CTRL); + RAL_WRITE(sc, RT2860_GPIO_CTRL, tmp & ~0x0808); + } } } static void rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; u_int chan, group; chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) return; - if (sc->mac_ver >= 0x3071) + if (sc->mac_ver >= 0x5390) + rt5390_set_chan(sc, chan); + else if (sc->mac_ver >= 0x3071) rt3090_set_chan(sc, chan); else rt2860_set_chan(sc, chan); @@ -4029,7 +4267,8 @@ rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) group = 3; /* XXX necessary only when group has changed! */ - rt2860_select_chan_group(sc, group); + if (sc->mac_ver < 0x5390) + rt2860_select_chan_group(sc, group); DELAY(1000); } @@ -4038,12 +4277,11 @@ static int rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap) { struct ieee80211com *ic = vap->iv_ic; - struct ieee80211_beacon_offsets bo; struct rt2860_txwi txwi; struct mbuf *m; int ridx; - if ((m = ieee80211_beacon_alloc(vap->iv_bss, &bo)) == NULL) + if ((m = ieee80211_beacon_alloc(vap->iv_bss)) == NULL) return ENOBUFS; memset(&txwi, 0, sizeof txwi); @@ -4072,8 +4310,7 @@ rt2860_setup_beacon(struct rt2860_softc *sc, struct ieee80211vap *vap) static void rt2860_enable_tsf_sync(struct rt2860_softc *sc) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211com *ic = &sc->sc_ic; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860reg.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860reg.h index 06c275d47f..9fc9a747fe 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860reg.h +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860reg.h @@ -15,7 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $OpenBSD: rt2860reg.h,v 1.30 2010/05/10 18:17:10 damien Exp $ - * $FreeBSD$ + * $FreeBSD: releng/11.1/sys/dev/ral/rt2860reg.h 301575 2016-06-08 02:37:23Z kevlo $ */ #define RT2860_NOISE_FLOOR -95 @@ -257,8 +257,17 @@ #define RT2860_TX_DMA_BUSY (1 << 1) #define RT2860_TX_DMA_EN (1 << 0) +/* flags for register WPDMA_RST_IDX */ +#define RT2860_RST_DRX_IDX0 (1 << 16) +#define RT2860_RST_DTX_IDX5 (1 << 5) +#define RT2860_RST_DTX_IDX4 (1 << 4) +#define RT2860_RST_DTX_IDX3 (1 << 3) +#define RT2860_RST_DTX_IDX2 (1 << 2) +#define RT2860_RST_DTX_IDX1 (1 << 1) +#define RT2860_RST_DTX_IDX0 (1 << 0) + /* possible flags for register DELAY_INT_CFG */ -#define RT2860_TXDLY_INT_EN (1 << 31) +#define RT2860_TXDLY_INT_EN (1U << 31) #define RT2860_TXMAX_PINT_SHIFT 24 #define RT2860_TXMAX_PTIME_SHIFT 16 #define RT2860_RXDLY_INT_EN (1 << 15) @@ -270,7 +279,7 @@ #define RT2860_GPIO_O_SHIFT 0 /* possible flags for register USB_DMA_CFG */ -#define RT2860_USB_TX_BUSY (1 << 31) +#define RT2860_USB_TX_BUSY (1U << 31) #define RT2860_USB_RX_BUSY (1 << 30) #define RT2860_USB_EPOUT_VLD_SHIFT 24 #define RT2860_USB_TX_EN (1 << 23) @@ -370,7 +379,7 @@ #define RT2860_TX0Q_PCNT_MASK 0x000000ff /* possible flags for register CAP_CTRL */ -#define RT2860_CAP_ADC_FEQ (1 << 31) +#define RT2860_CAP_ADC_FEQ (1U << 31) #define RT2860_CAP_START (1 << 30) #define RT2860_MAN_TRIG (1 << 29) #define RT2860_TRIG_OFFSET_SHIFT 16 @@ -381,7 +390,7 @@ #define RT3070_RF_WRITE (1 << 16) /* possible flags for register EFUSE_CTRL */ -#define RT3070_SEL_EFUSE (1 << 31) +#define RT3070_SEL_EFUSE (1U << 31) #define RT3070_EFSROM_KICK (1 << 30) #define RT3070_EFSROM_AIN_MASK 0x03ff0000 #define RT3070_EFSROM_AIN_SHIFT 16 @@ -420,7 +429,7 @@ #define RT2860_BBP_DATA_SHIFT 0 /* possible flags for register RF_CSR_CFG0 */ -#define RT2860_RF_REG_CTRL (1 << 31) +#define RT2860_RF_REG_CTRL (1U << 31) #define RT2860_RF_LE_SEL1 (1 << 30) #define RT2860_RF_LE_STBY (1 << 29) #define RT2860_RF_REG_WIDTH_SHIFT 24 @@ -455,7 +464,7 @@ #define RT2860_SLOT_TIME 0 /* possible flags for register NAV_TIME_CFG */ -#define RT2860_NAV_UPD (1 << 31) +#define RT2860_NAV_UPD (1U << 31) #define RT2860_NAV_UPD_VAL_SHIFT 16 #define RT2860_NAV_CLR_EN (1 << 15) #define RT2860_NAV_TIMER_SHIFT 0 @@ -509,7 +518,7 @@ #define RT2860_WAKEUP_LEAD_TIME_SHIFT 0 /* possible flags for register TX_PIN_CFG */ -#define RT3593_LNA_PE_G2_POL (1 << 31) +#define RT3593_LNA_PE_G2_POL (1U << 31) #define RT3593_LNA_PE_A2_POL (1 << 30) #define RT3593_LNA_PE_G2_EN (1 << 29) #define RT3593_LNA_PE_A2_EN (1 << 28) @@ -699,6 +708,7 @@ /* possible flags for RT3020 RF register 1 */ #define RT3070_RF_BLOCK (1 << 0) +#define RT3070_PLL_PD (1 << 1) #define RT3070_RX0_PD (1 << 2) #define RT3070_TX0_PD (1 << 3) #define RT3070_RX1_PD (1 << 4) @@ -750,6 +760,22 @@ #define RT3090_DEF_LNA 10 +/* possible flags for RT5390 RF register 38 */ +#define RT5390_RX_LO1 (1 << 5) + +/* possible flags for RT5390 RF register 39 */ +#define RT5390_RX_LO2 (1 << 7) + +/* possible flags for RT5390 RF register 42 */ +#define RT5390_RX_CTB (1 << 6) + +/* possible flags for RT5390 BBP register 4 */ +#define RT5390_MAC_IF_CTRL (1 << 6) + +/* possible flags for RT5390 BBP register 105 */ +#define RT5390_MLD (1 << 2) +#define RT5390_SIG_MODULATION (1 << 3) + /* RT2860 TX descriptor */ struct rt2860_txd { uint32_t sdp0; /* Segment Data Pointer 0 */ @@ -883,17 +909,19 @@ struct rt2860_rxwi { #define RT2860_RF3 1 #define RT2860_RF4 3 -#define RT2860_RF_2820 1 /* 2T3R */ -#define RT2860_RF_2850 2 /* dual-band 2T3R */ -#define RT2860_RF_2720 3 /* 1T2R */ -#define RT2860_RF_2750 4 /* dual-band 1T2R */ -#define RT3070_RF_3020 5 /* 1T1R */ -#define RT3070_RF_2020 6 /* b/g */ -#define RT3070_RF_3021 7 /* 1T2R */ -#define RT3070_RF_3022 8 /* 2T2R */ -#define RT3070_RF_3052 9 /* dual-band 2T2R */ -#define RT3070_RF_3320 11 /* 1T1R */ -#define RT3070_RF_3053 13 /* dual-band 3T3R */ +#define RT2860_RF_2820 0x0001 /* 2T3R */ +#define RT2860_RF_2850 0x0002 /* dual-band 2T3R */ +#define RT2860_RF_2720 0x0003 /* 1T2R */ +#define RT2860_RF_2750 0x0004 /* dual-band 1T2R */ +#define RT3070_RF_3020 0x0005 /* 1T1R */ +#define RT3070_RF_2020 0x0006 /* b/g */ +#define RT3070_RF_3021 0x0007 /* 1T2R */ +#define RT3070_RF_3022 0x0008 /* 2T2R */ +#define RT3070_RF_3052 0x0009 /* dual-band 2T2R */ +#define RT3070_RF_3320 0x000b /* 1T1R */ +#define RT3070_RF_3053 0x000d /* dual-band 3T3R */ +#define RT5390_RF_5360 0x5360 /* 1T1R */ +#define RT5390_RF_5390 0x5390 /* 1T1R */ /* USB commands for RT2870 only */ #define RT2870_RESET 1 @@ -904,6 +932,7 @@ struct rt2860_rxwi { #define RT2860_EEPROM_DELAY 1 /* minimum hold time (microsecond) */ +#define RT2860_EEPROM_CHIPID 0x00 #define RT2860_EEPROM_VERSION 0x01 #define RT2860_EEPROM_MAC01 0x02 #define RT2860_EEPROM_MAC23 0x03 @@ -1006,14 +1035,17 @@ static const struct rt2860_rate { */ #define RT2860_DEF_MAC \ { RT2860_BCN_OFFSET0, 0xf8f0e8e0 }, \ + { RT2860_BCN_OFFSET1, 0x6f77d0c8 }, \ { RT2860_LEGACY_BASIC_RATE, 0x0000013f }, \ { RT2860_HT_BASIC_RATE, 0x00008003 }, \ { RT2860_MAC_SYS_CTRL, 0x00000000 }, \ + { RT2860_RX_FILTR_CFG, 0x00017f97 }, \ { RT2860_BKOFF_SLOT_CFG, 0x00000209 }, \ { RT2860_TX_SW_CFG0, 0x00000000 }, \ { RT2860_TX_SW_CFG1, 0x00080606 }, \ { RT2860_TX_LINK_CFG, 0x00001020 }, \ { RT2860_TX_TIMEOUT_CFG, 0x000a2090 }, \ + { RT2860_MAX_LEN_CFG, 0x00001f00 }, \ { RT2860_LED_CFG, 0x7f031e46 }, \ { RT2860_WMM_AIFSN_CFG, 0x00002273 }, \ { RT2860_WMM_CWMIN_CFG, 0x00002344 }, \ @@ -1028,42 +1060,9 @@ static const struct rt2860_rate { { RT2860_MM20_PROT_CFG, 0x01744004 }, \ { RT2860_MM40_PROT_CFG, 0x03f54084 }, \ { RT2860_TXOP_CTRL_CFG, 0x0000583f }, \ - { RT2860_TXOP_HLDR_ET, 0x00000002 }, \ { RT2860_TX_RTS_CFG, 0x00092b20 }, \ { RT2860_EXP_ACK_TIME, 0x002400ca }, \ - { RT2860_XIFS_TIME_CFG, 0x33a41010 }, \ - { RT2860_PWR_PIN_CFG, 0x00000003 } - -/* XXX only a few registers differ from above, try to merge? */ -#define RT2870_DEF_MAC \ - { RT2860_BCN_OFFSET0, 0xf8f0e8e0 }, \ - { RT2860_LEGACY_BASIC_RATE, 0x0000013f }, \ - { RT2860_HT_BASIC_RATE, 0x00008003 }, \ - { RT2860_MAC_SYS_CTRL, 0x00000000 }, \ - { RT2860_BKOFF_SLOT_CFG, 0x00000209 }, \ - { RT2860_TX_SW_CFG0, 0x00000000 }, \ - { RT2860_TX_SW_CFG1, 0x00080606 }, \ - { RT2860_TX_LINK_CFG, 0x00001020 }, \ - { RT2860_TX_TIMEOUT_CFG, 0x000a2090 }, \ - { RT2860_LED_CFG, 0x7f031e46 }, \ - { RT2860_WMM_AIFSN_CFG, 0x00002273 }, \ - { RT2860_WMM_CWMIN_CFG, 0x00002344 }, \ - { RT2860_WMM_CWMAX_CFG, 0x000034aa }, \ - { RT2860_MAX_PCNT, 0x1f3fbf9f }, \ - { RT2860_TX_RTY_CFG, 0x47d01f0f }, \ - { RT2860_AUTO_RSP_CFG, 0x00000013 }, \ - { RT2860_CCK_PROT_CFG, 0x05740003 }, \ - { RT2860_OFDM_PROT_CFG, 0x05740003 }, \ - { RT2860_PBF_CFG, 0x00f40006 }, \ - { RT2860_WPDMA_GLO_CFG, 0x00000030 }, \ - { RT2860_GF20_PROT_CFG, 0x01744004 }, \ - { RT2860_GF40_PROT_CFG, 0x03f44084 }, \ - { RT2860_MM20_PROT_CFG, 0x01744004 }, \ - { RT2860_MM40_PROT_CFG, 0x03f44084 }, \ - { RT2860_TXOP_CTRL_CFG, 0x0000583f }, \ { RT2860_TXOP_HLDR_ET, 0x00000002 }, \ - { RT2860_TX_RTS_CFG, 0x00092b20 }, \ - { RT2860_EXP_ACK_TIME, 0x002400ca }, \ { RT2860_XIFS_TIME_CFG, 0x33a41010 }, \ { RT2860_PWR_PIN_CFG, 0x00000003 } @@ -1073,6 +1072,7 @@ static const struct rt2860_rate { #define RT2860_DEF_BBP \ { 65, 0x2c }, \ { 66, 0x38 }, \ + { 68, 0x0b }, \ { 69, 0x12 }, \ { 70, 0x0a }, \ { 73, 0x10 }, \ @@ -1087,6 +1087,30 @@ static const struct rt2860_rate { { 105, 0x05 }, \ { 106, 0x35 } +#define RT5390_DEF_BBP \ + { 31, 0x08 }, \ + { 65, 0x2c }, \ + { 66, 0x38 }, \ + { 68, 0x0b }, \ + { 69, 0x12 }, \ + { 70, 0x0a }, \ + { 73, 0x13 }, \ + { 75, 0x46 }, \ + { 76, 0x28 }, \ + { 77, 0x59 }, \ + { 81, 0x37 }, \ + { 82, 0x62 }, \ + { 83, 0x7a }, \ + { 84, 0x19 }, \ + { 86, 0x38 }, \ + { 91, 0x04 }, \ + { 92, 0x02 }, \ + { 103, 0xc0 }, \ + { 104, 0x92 }, \ + { 105, 0x3c }, \ + { 106, 0x03 }, \ + { 128, 0x12 }, \ + /* * Default settings for RF registers; values derived from the reference driver. */ @@ -1204,7 +1228,7 @@ static const struct rt2860_rate { { 4, 0x40 }, \ { 5, 0x03 }, \ { 6, 0x02 }, \ - { 7, 0x70 }, \ + { 7, 0x60 }, \ { 9, 0x0f }, \ { 10, 0x41 }, \ { 11, 0x21 }, \ @@ -1218,38 +1242,125 @@ static const struct rt2860_rate { { 20, 0xba }, \ { 21, 0xdb }, \ { 24, 0x16 }, \ - { 25, 0x01 }, \ + { 25, 0x03 }, \ { 29, 0x1f } -#define RT3572_DEF_RF \ - { 0, 0x70 }, \ - { 1, 0x81 }, \ - { 2, 0xf1 }, \ - { 3, 0x02 }, \ - { 4, 0x4c }, \ - { 5, 0x05 }, \ - { 6, 0x4a }, \ - { 7, 0xd8 }, \ - { 9, 0xc3 }, \ - { 10, 0xf1 }, \ - { 11, 0xb9 }, \ - { 12, 0x70 }, \ - { 13, 0x65 }, \ - { 14, 0xa0 }, \ - { 15, 0x53 }, \ - { 16, 0x4c }, \ - { 17, 0x23 }, \ - { 18, 0xac }, \ - { 19, 0x93 }, \ - { 20, 0xb3 }, \ - { 21, 0xd0 }, \ - { 22, 0x00 }, \ - { 23, 0x3c }, \ - { 24, 0x16 }, \ - { 25, 0x15 }, \ - { 26, 0x85 }, \ - { 27, 0x00 }, \ +#define RT5390_DEF_RF \ + { 1, 0x0f }, \ + { 2, 0x80 }, \ + { 3, 0x88 }, \ + { 5, 0x10 }, \ + { 6, 0xe0 }, \ + { 7, 0x00 }, \ + { 10, 0x53 }, \ + { 11, 0x4a }, \ + { 12, 0x46 }, \ + { 13, 0x9f }, \ + { 14, 0x00 }, \ + { 15, 0x00 }, \ + { 16, 0x00 }, \ + { 18, 0x03 }, \ + { 19, 0x00 }, \ + { 20, 0x00 }, \ + { 21, 0x00 }, \ + { 22, 0x20 }, \ + { 23, 0x00 }, \ + { 24, 0x00 }, \ + { 25, 0x80 }, \ + { 26, 0x00 }, \ + { 27, 0x09 }, \ { 28, 0x00 }, \ - { 29, 0x9b }, \ - { 30, 0x09 }, \ - { 31, 0x10 } + { 29, 0x10 }, \ + { 30, 0x10 }, \ + { 31, 0x80 }, \ + { 32, 0x80 }, \ + { 33, 0x00 }, \ + { 34, 0x07 }, \ + { 35, 0x12 }, \ + { 36, 0x00 }, \ + { 37, 0x08 }, \ + { 38, 0x85 }, \ + { 39, 0x1b }, \ + { 40, 0x0b }, \ + { 41, 0xbb }, \ + { 42, 0xd2 }, \ + { 43, 0x9a }, \ + { 44, 0x0e }, \ + { 45, 0xa2 }, \ + { 46, 0x73 }, \ + { 47, 0x00 }, \ + { 48, 0x10 }, \ + { 49, 0x94 }, \ + { 52, 0x38 }, \ + { 53, 0x00 }, \ + { 54, 0x78 }, \ + { 55, 0x23 }, \ + { 56, 0x22 }, \ + { 57, 0x80 }, \ + { 58, 0x7f }, \ + { 59, 0x07 }, \ + { 60, 0x45 }, \ + { 61, 0xd1 }, \ + { 62, 0x00 }, \ + { 63, 0x00 } + +#define RT5392_DEF_RF \ + { 1, 0x17 }, \ + { 2, 0x80 }, \ + { 3, 0x88 }, \ + { 5, 0x10 }, \ + { 6, 0xe0 }, \ + { 7, 0x00 }, \ + { 10, 0x53 }, \ + { 11, 0x4a }, \ + { 12, 0x46 }, \ + { 13, 0x9f }, \ + { 14, 0x00 }, \ + { 15, 0x00 }, \ + { 16, 0x00 }, \ + { 18, 0x03 }, \ + { 19, 0x4d }, \ + { 20, 0x00 }, \ + { 21, 0x8d }, \ + { 22, 0x20 }, \ + { 23, 0x0b }, \ + { 24, 0x44 }, \ + { 25, 0x80 }, \ + { 26, 0x82 }, \ + { 27, 0x09 }, \ + { 28, 0x00 }, \ + { 29, 0x10 }, \ + { 30, 0x10 }, \ + { 31, 0x80 }, \ + { 32, 0x80 }, \ + { 33, 0xc0 }, \ + { 34, 0x07 }, \ + { 35, 0x12 }, \ + { 36, 0x00 }, \ + { 37, 0x08 }, \ + { 38, 0x89 }, \ + { 39, 0x1b }, \ + { 40, 0x0f }, \ + { 41, 0xbb }, \ + { 42, 0xd5 }, \ + { 43, 0x9b }, \ + { 44, 0x0e }, \ + { 45, 0xa2 }, \ + { 46, 0x73 }, \ + { 47, 0x0c }, \ + { 48, 0x10 }, \ + { 49, 0x94 }, \ + { 50, 0x94 }, \ + { 51, 0x3a }, \ + { 52, 0x48 }, \ + { 53, 0x44 }, \ + { 54, 0x38 }, \ + { 55, 0x43 }, \ + { 56, 0xa1 }, \ + { 57, 0x00 }, \ + { 58, 0x39 }, \ + { 59, 0x07 }, \ + { 60, 0x45 }, \ + { 61, 0x91 }, \ + { 62, 0x39 }, \ + { 63, 0x00 } diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860var.h b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860var.h index 653502be00..a3ac1a0899 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860var.h +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/dev/ral/rt2860var.h @@ -15,7 +15,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $OpenBSD: rt2860var.h,v 1.20 2010/09/07 16:21:42 deraadt Exp $ - * $FreeBSD$ + * $FreeBSD: releng/11.1/sys/dev/ral/rt2860var.h 300657 2016-05-25 06:29:23Z sgalabov $ */ #define RT2860_TX_RING_COUNT 64 @@ -38,7 +38,7 @@ struct rt2860_rx_radiotap_header { uint8_t wr_antenna; int8_t wr_antsignal; int8_t wr_antnoise; -} __packed; +} __packed __aligned(8); #define RT2860_RX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_TSFT) | \ @@ -55,7 +55,7 @@ struct rt2860_tx_radiotap_header { uint8_t wt_rate; uint16_t wt_chan_freq; uint16_t wt_chan_flags; -} __packed; +} __packed __aligned(8); #define RT2860_TX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ @@ -115,13 +115,13 @@ struct rt2860_vap { #define RT2860_VAP(vap) ((struct rt2860_vap *)(vap)) struct rt2860_softc { - struct ifnet *sc_ifp; + struct ieee80211com sc_ic; + struct mbufq sc_snd; + struct mtx sc_mtx; device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; - struct mtx sc_mtx; - struct callout watchdog_ch; int sc_invalid; @@ -139,6 +139,7 @@ struct rt2860_softc { #define RT2860_ENABLED (1 << 0) #define RT2860_ADVANCED_PS (1 << 1) #define RT2860_PCIE (1 << 2) +#define RT2860_RUNNING (1 << 3) struct ieee80211_node *wcid2ni[RT2860_WCID_MAX]; @@ -158,7 +159,7 @@ struct rt2860_softc { uint16_t mac_ver; uint16_t mac_rev; - uint8_t rf_rev; + uint16_t rf_rev; uint8_t freq; uint8_t ntxchains; uint8_t nrxchains; @@ -193,9 +194,7 @@ struct rt2860_softc { uint32_t txpow40mhz_5ghz[5]; struct rt2860_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; struct rt2860_tx_radiotap_header sc_txtap; - int sc_txtap_len; #if defined(__HAIKU__) uint32_t sc_intr_status; diff --git a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/glue.c b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/glue.c index e07c1b438a..ae92a5b4ae 100644 --- a/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/glue.c +++ b/src/add-ons/kernel/drivers/network/wlan/ralinkwifi/glue.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -26,9 +27,12 @@ HAIKU_FBSD_WLAN_DRIVER_GLUE(ralinkwifi, ral, pci) HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_SWI_TASKQUEUE | FBSD_WLAN); HAIKU_FIRMWARE_VERSION(0); -HAIKU_FIRMWARE_NAME_MAP(4) = {{"rt2561fw", "rt2561.bin"}, - {"rt2561sfw", "rt2561s.bin"}, {"rt2661fw", "rt2661.bin"}, - {"rt2860fw", "rt2860.bin"}}; +HAIKU_FIRMWARE_NAME_MAP(4) = { + {"rt2561fw", "rt2561.bin"}, + {"rt2561sfw", "rt2561s.bin"}, + {"rt2661fw", "rt2661.bin"}, + {"rt2860fw", "rt2860.bin"} +}; NO_HAIKU_FBSD_MII_DRIVER(); NO_HAIKU_REENABLE_INTERRUPTS(); @@ -43,14 +47,13 @@ HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) { struct rt2560_softc* sc = (struct rt2560_softc*)device_get_softc(dev); // sc_ifp is common between context data structures - struct ifnet* ifp = sc->sc_ifp; switch (pci_get_device(dev)) { case 0x0201: // disable interrupts RAL_WRITE(sc, RT2560_CSR8, 0xffffffff); - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RT2560_F_RUNNING)) { // don't re-enable interrupts if we're shutting down return 0; } @@ -62,7 +65,7 @@ HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev) RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f); RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff); - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(sc->sc_flags & RAL_RUNNING)) { // don't re-enable interrupts if we're shutting down return 0; }