Home | History | Annotate | Line # | Download | only in usb
if_rum.c revision 1.3.2.3.2.1
      1          1.1     joerg /*	$OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $	*/
      2  1.3.2.3.2.1  wrstuden /*	$NetBSD: if_rum.c,v 1.3.2.3.2.1 2007/09/30 20:27:51 wrstuden Exp $	*/
      3          1.1     joerg 
      4          1.1     joerg /*-
      5          1.1     joerg  * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini (at) free.fr>
      6          1.1     joerg  * Copyright (c) 2006 Niall O'Higgins <niallo (at) openbsd.org>
      7          1.1     joerg  *
      8          1.1     joerg  * Permission to use, copy, modify, and distribute this software for any
      9          1.1     joerg  * purpose with or without fee is hereby granted, provided that the above
     10          1.1     joerg  * copyright notice and this permission notice appear in all copies.
     11          1.1     joerg  *
     12          1.1     joerg  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     13          1.1     joerg  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     14          1.1     joerg  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     15          1.1     joerg  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     16          1.1     joerg  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     17          1.1     joerg  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     18          1.1     joerg  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     19          1.1     joerg  */
     20          1.1     joerg 
     21          1.1     joerg /*-
     22          1.1     joerg  * Ralink Technology RT2501USB/RT2601USB chipset driver
     23          1.1     joerg  * http://www.ralinktech.com/
     24          1.1     joerg  */
     25          1.1     joerg 
     26          1.2   xtraeme #include <sys/cdefs.h>
     27  1.3.2.3.2.1  wrstuden __KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.3.2.3.2.1 2007/09/30 20:27:51 wrstuden Exp $");
     28          1.2   xtraeme 
     29          1.1     joerg #include "bpfilter.h"
     30          1.1     joerg 
     31          1.1     joerg #include <sys/param.h>
     32          1.1     joerg #include <sys/sockio.h>
     33          1.1     joerg #include <sys/sysctl.h>
     34          1.1     joerg #include <sys/mbuf.h>
     35          1.1     joerg #include <sys/kernel.h>
     36          1.1     joerg #include <sys/socket.h>
     37          1.1     joerg #include <sys/systm.h>
     38          1.1     joerg #include <sys/malloc.h>
     39          1.1     joerg #include <sys/conf.h>
     40          1.1     joerg #include <sys/device.h>
     41          1.1     joerg 
     42          1.1     joerg #include <machine/bus.h>
     43          1.1     joerg #include <machine/endian.h>
     44          1.1     joerg #include <machine/intr.h>
     45          1.1     joerg 
     46          1.1     joerg #if NBPFILTER > 0
     47          1.1     joerg #include <net/bpf.h>
     48          1.1     joerg #endif
     49          1.1     joerg #include <net/if.h>
     50          1.1     joerg #include <net/if_arp.h>
     51          1.1     joerg #include <net/if_dl.h>
     52          1.1     joerg #include <net/if_ether.h>
     53          1.1     joerg #include <net/if_media.h>
     54          1.1     joerg #include <net/if_types.h>
     55          1.1     joerg 
     56          1.1     joerg #include <netinet/in.h>
     57          1.1     joerg #include <netinet/in_systm.h>
     58          1.1     joerg #include <netinet/in_var.h>
     59          1.1     joerg #include <netinet/ip.h>
     60          1.1     joerg 
     61          1.1     joerg #include <net80211/ieee80211_netbsd.h>
     62          1.1     joerg #include <net80211/ieee80211_var.h>
     63          1.1     joerg #include <net80211/ieee80211_amrr.h>
     64          1.1     joerg #include <net80211/ieee80211_radiotap.h>
     65          1.1     joerg 
     66          1.1     joerg #include <dev/firmload.h>
     67          1.1     joerg 
     68          1.1     joerg #include <dev/usb/usb.h>
     69          1.1     joerg #include <dev/usb/usbdi.h>
     70          1.1     joerg #include <dev/usb/usbdi_util.h>
     71          1.1     joerg #include <dev/usb/usbdevs.h>
     72          1.1     joerg 
     73          1.1     joerg #include <dev/usb/if_rumreg.h>
     74          1.1     joerg #include <dev/usb/if_rumvar.h>
     75          1.1     joerg 
     76          1.1     joerg #ifdef USB_DEBUG
     77          1.1     joerg #define RUM_DEBUG
     78          1.1     joerg #endif
     79          1.1     joerg 
     80          1.1     joerg #ifdef RUM_DEBUG
     81          1.1     joerg #define DPRINTF(x)	do { if (rum_debug) logprintf x; } while (0)
     82          1.1     joerg #define DPRINTFN(n, x)	do { if (rum_debug >= (n)) logprintf x; } while (0)
     83          1.1     joerg int rum_debug = 0;
     84          1.1     joerg #else
     85          1.1     joerg #define DPRINTF(x)
     86          1.1     joerg #define DPRINTFN(n, x)
     87          1.1     joerg #endif
     88          1.1     joerg 
     89          1.1     joerg /* various supported device vendors/products */
     90          1.1     joerg static const struct usb_devno rum_devs[] = {
     91  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_HWU54DM },
     92  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_2 },
     93  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_3 },
     94  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_4 },
     95  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_AMIT,		USB_PRODUCT_AMIT_CGWLUSB2GO },
     96      1.3.2.3       snj 	{ USB_VENDOR_ASUSTEK,		USB_PRODUCT_ASUSTEK_WL167G_2 },
     97  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_ASUSTEK,		USB_PRODUCT_ASUSTEK_WL167G_3 },
     98          1.1     joerg 	{ USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D7050A },
     99          1.1     joerg 	{ USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D9050V3 },
    100          1.1     joerg 	{ USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GC },
    101  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GR },
    102          1.1     joerg 	{ USB_VENDOR_CONCEPTRONIC,	USB_PRODUCT_CONCEPTRONIC_C54RU2 },
    103          1.1     joerg 	{ USB_VENDOR_DICKSMITH,		USB_PRODUCT_DICKSMITH_CWD854F },
    104          1.1     joerg 	{ USB_VENDOR_DICKSMITH,		USB_PRODUCT_DICKSMITH_RT2573 },
    105          1.1     joerg 	{ USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWLG122C1 },
    106          1.1     joerg 	{ USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_WUA1340 },
    107          1.1     joerg 	{ USB_VENDOR_GIGABYTE,		USB_PRODUCT_GIGABYTE_GNWB01GS },
    108  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_GIGABYTE,		USB_PRODUCT_GIGABYTE_GNWI05GS },
    109          1.1     joerg 	{ USB_VENDOR_GIGASET,		USB_PRODUCT_GIGASET_RT2573 },
    110          1.1     joerg 	{ USB_VENDOR_GOODWAY,		USB_PRODUCT_GOODWAY_RT2573 },
    111  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_GUILLEMOT,		USB_PRODUCT_GUILLEMOT_HWGUSB254LB },
    112  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_GUILLEMOT,		USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP },
    113          1.1     joerg 	{ USB_VENDOR_HUAWEI3COM,	USB_PRODUCT_HUAWEI3COM_RT2573 },
    114  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_G54HP },
    115  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_SG54HP },
    116          1.1     joerg 	{ USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573 },
    117          1.1     joerg 	{ USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_2 },
    118          1.1     joerg 	{ USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_3 },
    119  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_4 },
    120  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_NOVATECH,		USB_PRODUCT_NOVATECH_RT2573 },
    121  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_PLANEX2,		USB_PRODUCT_PLANEX2_GWUS54HP },
    122  1.3.2.3.2.1  wrstuden 	{ USB_VENDOR_PLANEX2,		USB_PRODUCT_PLANEX2_GWUS54MINI2 },
    123          1.1     joerg 	{ USB_VENDOR_PLANEX2,		USB_PRODUCT_PLANEX2_GWUSMM },
    124          1.1     joerg 	{ USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573 },
    125          1.1     joerg 	{ USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573_2 },
    126          1.1     joerg 	{ USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573 },
    127          1.3  christos 	{ USB_VENDOR_RALINK_2,          USB_PRODUCT_RALINK_2_RT2573 },
    128          1.1     joerg 	{ USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2671 },
    129          1.1     joerg 	{ USB_VENDOR_SITECOMEU,		USB_PRODUCT_SITECOMEU_WL113R2 },
    130          1.1     joerg 	{ USB_VENDOR_SITECOMEU,		USB_PRODUCT_SITECOMEU_WL172 },
    131          1.1     joerg 	{ USB_VENDOR_SURECOM,		USB_PRODUCT_SURECOM_RT2573 }
    132          1.1     joerg };
    133          1.1     joerg 
    134          1.1     joerg Static int		rum_attachhook(void *);
    135          1.1     joerg Static int		rum_alloc_tx_list(struct rum_softc *);
    136          1.1     joerg Static void		rum_free_tx_list(struct rum_softc *);
    137          1.1     joerg Static int		rum_alloc_rx_list(struct rum_softc *);
    138          1.1     joerg Static void		rum_free_rx_list(struct rum_softc *);
    139          1.1     joerg Static int		rum_media_change(struct ifnet *);
    140          1.1     joerg Static void		rum_next_scan(void *);
    141          1.1     joerg Static void		rum_task(void *);
    142          1.1     joerg Static int		rum_newstate(struct ieee80211com *,
    143          1.1     joerg 			    enum ieee80211_state, int);
    144          1.1     joerg Static void		rum_txeof(usbd_xfer_handle, usbd_private_handle,
    145          1.1     joerg 			    usbd_status);
    146          1.1     joerg Static void		rum_rxeof(usbd_xfer_handle, usbd_private_handle,
    147          1.1     joerg 			    usbd_status);
    148          1.1     joerg #if NBPFILTER > 0
    149          1.1     joerg Static uint8_t		rum_rxrate(struct rum_rx_desc *);
    150          1.1     joerg #endif
    151          1.1     joerg Static int		rum_ack_rate(struct ieee80211com *, int);
    152          1.1     joerg Static uint16_t		rum_txtime(int, int, uint32_t);
    153          1.1     joerg Static uint8_t		rum_plcp_signal(int);
    154          1.1     joerg Static void		rum_setup_tx_desc(struct rum_softc *,
    155          1.1     joerg 			    struct rum_tx_desc *, uint32_t, uint16_t, int,
    156          1.1     joerg 			    int);
    157          1.1     joerg Static int		rum_tx_mgt(struct rum_softc *, struct mbuf *,
    158          1.1     joerg 			    struct ieee80211_node *);
    159          1.1     joerg Static int		rum_tx_data(struct rum_softc *, struct mbuf *,
    160          1.1     joerg 			    struct ieee80211_node *);
    161          1.1     joerg Static void		rum_start(struct ifnet *);
    162          1.1     joerg Static void		rum_watchdog(struct ifnet *);
    163          1.1     joerg Static int		rum_ioctl(struct ifnet *, u_long, caddr_t);
    164          1.1     joerg Static void		rum_eeprom_read(struct rum_softc *, uint16_t, void *,
    165          1.1     joerg 			    int);
    166          1.1     joerg Static uint32_t		rum_read(struct rum_softc *, uint16_t);
    167          1.1     joerg Static void		rum_read_multi(struct rum_softc *, uint16_t, void *,
    168          1.1     joerg 			    int);
    169          1.1     joerg Static void		rum_write(struct rum_softc *, uint16_t, uint32_t);
    170          1.1     joerg Static void		rum_write_multi(struct rum_softc *, uint16_t, void *,
    171          1.1     joerg 			    size_t);
    172          1.1     joerg Static void		rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
    173          1.1     joerg Static uint8_t		rum_bbp_read(struct rum_softc *, uint8_t);
    174          1.1     joerg Static void		rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
    175          1.1     joerg Static void		rum_select_antenna(struct rum_softc *);
    176          1.1     joerg Static void		rum_enable_mrr(struct rum_softc *);
    177          1.1     joerg Static void		rum_set_txpreamble(struct rum_softc *);
    178          1.1     joerg Static void		rum_set_basicrates(struct rum_softc *);
    179          1.1     joerg Static void		rum_select_band(struct rum_softc *,
    180          1.1     joerg 			    struct ieee80211_channel *);
    181          1.1     joerg Static void		rum_set_chan(struct rum_softc *,
    182          1.1     joerg 			    struct ieee80211_channel *);
    183          1.1     joerg Static void		rum_enable_tsf_sync(struct rum_softc *);
    184          1.1     joerg Static void		rum_update_slot(struct rum_softc *);
    185          1.1     joerg Static void		rum_set_bssid(struct rum_softc *, const uint8_t *);
    186          1.1     joerg Static void		rum_set_macaddr(struct rum_softc *, const uint8_t *);
    187          1.1     joerg Static void		rum_update_promisc(struct rum_softc *);
    188          1.1     joerg Static const char	*rum_get_rf(int);
    189          1.1     joerg Static void		rum_read_eeprom(struct rum_softc *);
    190          1.1     joerg Static int		rum_bbp_init(struct rum_softc *);
    191          1.1     joerg Static int		rum_init(struct ifnet *);
    192          1.1     joerg Static void		rum_stop(struct ifnet *, int);
    193          1.1     joerg Static int		rum_load_microcode(struct rum_softc *, const u_char *,
    194          1.1     joerg 			    size_t);
    195          1.1     joerg Static int		rum_prepare_beacon(struct rum_softc *);
    196          1.1     joerg Static void		rum_amrr_start(struct rum_softc *,
    197          1.1     joerg 			    struct ieee80211_node *);
    198          1.1     joerg Static void		rum_amrr_timeout(void *);
    199          1.1     joerg Static void		rum_amrr_update(usbd_xfer_handle, usbd_private_handle,
    200          1.1     joerg 			    usbd_status status);
    201          1.1     joerg 
    202          1.1     joerg /*
    203          1.1     joerg  * Supported rates for 802.11a/b/g modes (in 500Kbps unit).
    204          1.1     joerg  */
    205          1.1     joerg static const struct ieee80211_rateset rum_rateset_11a =
    206          1.1     joerg 	{ 8, { 12, 18, 24, 36, 48, 72, 96, 108 } };
    207          1.1     joerg 
    208          1.1     joerg static const struct ieee80211_rateset rum_rateset_11b =
    209          1.1     joerg 	{ 4, { 2, 4, 11, 22 } };
    210          1.1     joerg 
    211          1.1     joerg static const struct ieee80211_rateset rum_rateset_11g =
    212          1.1     joerg 	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
    213          1.1     joerg 
    214          1.1     joerg static const struct {
    215          1.1     joerg 	uint32_t	reg;
    216          1.1     joerg 	uint32_t	val;
    217          1.1     joerg } rum_def_mac[] = {
    218          1.1     joerg 	RT2573_DEF_MAC
    219          1.1     joerg };
    220          1.1     joerg 
    221          1.1     joerg static const struct {
    222          1.1     joerg 	uint8_t	reg;
    223          1.1     joerg 	uint8_t	val;
    224          1.1     joerg } rum_def_bbp[] = {
    225          1.1     joerg 	RT2573_DEF_BBP
    226          1.1     joerg };
    227          1.1     joerg 
    228          1.1     joerg static const struct rfprog {
    229          1.1     joerg 	uint8_t		chan;
    230          1.1     joerg 	uint32_t	r1, r2, r3, r4;
    231          1.1     joerg }  rum_rf5226[] = {
    232          1.1     joerg 	RT2573_RF5226
    233          1.1     joerg }, rum_rf5225[] = {
    234          1.1     joerg 	RT2573_RF5225
    235          1.1     joerg };
    236          1.1     joerg 
    237          1.1     joerg USB_DECLARE_DRIVER(rum);
    238          1.1     joerg 
    239          1.1     joerg USB_MATCH(rum)
    240          1.1     joerg {
    241          1.1     joerg 	USB_MATCH_START(rum, uaa);
    242          1.1     joerg 
    243          1.1     joerg 	if (uaa->iface != NULL)
    244          1.1     joerg 		return UMATCH_NONE;
    245          1.1     joerg 
    246          1.1     joerg 	return (usb_lookup(rum_devs, uaa->vendor, uaa->product) != NULL) ?
    247          1.1     joerg 	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
    248          1.1     joerg }
    249          1.1     joerg 
    250          1.1     joerg Static int
    251          1.1     joerg rum_attachhook(void *xsc)
    252          1.1     joerg {
    253          1.1     joerg 	struct rum_softc *sc = xsc;
    254          1.1     joerg 	firmware_handle_t fwh;
    255          1.1     joerg 	const char *name = "rum-rt2573";
    256          1.1     joerg 	u_char *ucode;
    257          1.1     joerg 	size_t size;
    258          1.1     joerg 	int error;
    259          1.1     joerg 
    260          1.1     joerg 	if ((error = firmware_open("rum", name, &fwh)) != 0) {
    261          1.1     joerg 		printf("%s: failed loadfirmware of file %s (error %d)\n",
    262          1.1     joerg 		    USBDEVNAME(sc->sc_dev), name, error);
    263          1.1     joerg 		return error;
    264          1.1     joerg 	}
    265          1.1     joerg 	size = firmware_get_size(fwh);
    266          1.1     joerg 	ucode = firmware_malloc(size);
    267          1.1     joerg 	if (ucode == NULL) {
    268          1.1     joerg 		printf("%s: failed to allocate firmware memory\n",
    269          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
    270          1.1     joerg 		firmware_close(fwh);
    271          1.1     joerg 		return ENOMEM;;
    272          1.1     joerg 	}
    273          1.1     joerg 	error = firmware_read(fwh, 0, ucode, size);
    274          1.1     joerg 	firmware_close(fwh);
    275          1.1     joerg 	if (error != 0) {
    276          1.1     joerg 		printf("%s: failed to read firmware (error %d)\n",
    277          1.1     joerg 		    USBDEVNAME(sc->sc_dev), error);
    278          1.1     joerg 		firmware_free(ucode, 0);
    279          1.1     joerg 		return error;
    280          1.1     joerg 	}
    281          1.1     joerg 
    282          1.1     joerg 	if (rum_load_microcode(sc, ucode, size) != 0) {
    283          1.1     joerg 		printf("%s: could not load 8051 microcode\n",
    284          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
    285          1.1     joerg 		firmware_free(ucode, 0);
    286          1.1     joerg 		return ENXIO;
    287          1.1     joerg 	}
    288          1.1     joerg 
    289          1.1     joerg 	firmware_free(ucode, 0);
    290          1.1     joerg 	sc->sc_flags |= RT2573_FWLOADED;
    291          1.1     joerg 
    292          1.1     joerg 	return 0;
    293          1.1     joerg }
    294          1.1     joerg 
    295          1.1     joerg USB_ATTACH(rum)
    296          1.1     joerg {
    297          1.1     joerg 	USB_ATTACH_START(rum, sc, uaa);
    298          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
    299          1.1     joerg 	struct ifnet *ifp = &sc->sc_if;
    300          1.1     joerg 	usb_interface_descriptor_t *id;
    301          1.1     joerg 	usb_endpoint_descriptor_t *ed;
    302          1.1     joerg 	usbd_status error;
    303          1.1     joerg 	char *devinfop;
    304          1.1     joerg 	int i, ntries;
    305          1.1     joerg 	uint32_t tmp;
    306          1.1     joerg 
    307          1.1     joerg 	sc->sc_udev = uaa->device;
    308          1.1     joerg 	sc->sc_flags = 0;
    309          1.1     joerg 
    310          1.1     joerg 	devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
    311          1.1     joerg 	USB_ATTACH_SETUP;
    312          1.1     joerg 	printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop);
    313          1.1     joerg 	usbd_devinfo_free(devinfop);
    314          1.1     joerg 
    315          1.1     joerg 	if (usbd_set_config_no(sc->sc_udev, RT2573_CONFIG_NO, 0) != 0) {
    316          1.1     joerg 		printf("%s: could not set configuration no\n",
    317          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
    318          1.1     joerg 		USB_ATTACH_ERROR_RETURN;
    319          1.1     joerg 	}
    320          1.1     joerg 
    321          1.1     joerg 	/* get the first interface handle */
    322          1.1     joerg 	error = usbd_device2interface_handle(sc->sc_udev, RT2573_IFACE_INDEX,
    323          1.1     joerg 	    &sc->sc_iface);
    324          1.1     joerg 	if (error != 0) {
    325          1.1     joerg 		printf("%s: could not get interface handle\n",
    326          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
    327          1.1     joerg 		USB_ATTACH_ERROR_RETURN;
    328          1.1     joerg 	}
    329          1.1     joerg 
    330          1.1     joerg 	/*
    331          1.1     joerg 	 * Find endpoints.
    332          1.1     joerg 	 */
    333          1.1     joerg 	id = usbd_get_interface_descriptor(sc->sc_iface);
    334          1.1     joerg 
    335          1.1     joerg 	sc->sc_rx_no = sc->sc_tx_no = -1;
    336          1.1     joerg 	for (i = 0; i < id->bNumEndpoints; i++) {
    337          1.1     joerg 		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
    338          1.1     joerg 		if (ed == NULL) {
    339          1.1     joerg 			printf("%s: no endpoint descriptor for iface %d\n",
    340          1.1     joerg 			    USBDEVNAME(sc->sc_dev), i);
    341          1.1     joerg 			USB_ATTACH_ERROR_RETURN;
    342          1.1     joerg 		}
    343          1.1     joerg 
    344          1.1     joerg 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    345          1.1     joerg 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
    346          1.1     joerg 			sc->sc_rx_no = ed->bEndpointAddress;
    347          1.1     joerg 		else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
    348          1.1     joerg 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
    349          1.1     joerg 			sc->sc_tx_no = ed->bEndpointAddress;
    350          1.1     joerg 	}
    351          1.1     joerg 	if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
    352          1.1     joerg 		printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev));
    353          1.1     joerg 		USB_ATTACH_ERROR_RETURN;
    354          1.1     joerg 	}
    355          1.1     joerg 
    356          1.1     joerg 	usb_init_task(&sc->sc_task, rum_task, sc);
    357          1.1     joerg 	callout_init(&sc->scan_ch);
    358          1.1     joerg 
    359          1.1     joerg 	sc->amrr.amrr_min_success_threshold =  1;
    360          1.1     joerg 	sc->amrr.amrr_max_success_threshold = 10;
    361          1.1     joerg 	callout_init(&sc->amrr_ch);
    362          1.1     joerg 
    363          1.1     joerg 	/* retrieve RT2573 rev. no */
    364          1.1     joerg 	for (ntries = 0; ntries < 1000; ntries++) {
    365          1.1     joerg 		if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
    366          1.1     joerg 			break;
    367          1.1     joerg 		DELAY(1000);
    368          1.1     joerg 	}
    369          1.1     joerg 	if (ntries == 1000) {
    370          1.1     joerg 		printf("%s: timeout waiting for chip to settle\n",
    371          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
    372          1.1     joerg 		USB_ATTACH_ERROR_RETURN;
    373          1.1     joerg 	}
    374          1.1     joerg 
    375          1.1     joerg 	/* retrieve MAC address and various other things from EEPROM */
    376          1.1     joerg 	rum_read_eeprom(sc);
    377          1.1     joerg 
    378          1.1     joerg 	printf("%s: MAC/BBP RT%04x (rev 0x%05x), RF %s, address %s\n",
    379          1.1     joerg 	    USBDEVNAME(sc->sc_dev), sc->macbbp_rev, tmp,
    380          1.1     joerg 	    rum_get_rf(sc->rf_rev), ether_sprintf(ic->ic_myaddr));
    381          1.1     joerg 
    382          1.1     joerg 	ic->ic_ifp = ifp;
    383          1.1     joerg 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
    384          1.1     joerg 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
    385          1.1     joerg 	ic->ic_state = IEEE80211_S_INIT;
    386          1.1     joerg 
    387          1.1     joerg 	/* set device capabilities */
    388          1.1     joerg 	ic->ic_caps =
    389          1.1     joerg 	    IEEE80211_C_IBSS |		/* IBSS mode supported */
    390          1.1     joerg 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
    391          1.1     joerg 	    IEEE80211_C_HOSTAP |	/* HostAp mode supported */
    392          1.1     joerg 	    IEEE80211_C_TXPMGT |	/* tx power management */
    393          1.1     joerg 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
    394          1.1     joerg 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
    395          1.1     joerg 	    IEEE80211_C_WPA;		/* 802.11i */
    396          1.1     joerg 
    397          1.1     joerg 	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) {
    398          1.1     joerg 		/* set supported .11a rates */
    399          1.1     joerg 		ic->ic_sup_rates[IEEE80211_MODE_11A] = rum_rateset_11a;
    400          1.1     joerg 
    401          1.1     joerg 		/* set supported .11a channels */
    402          1.1     joerg 		for (i = 34; i <= 46; i += 4) {
    403          1.1     joerg 			ic->ic_channels[i].ic_freq =
    404          1.1     joerg 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
    405          1.1     joerg 			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
    406          1.1     joerg 		}
    407          1.1     joerg 		for (i = 36; i <= 64; i += 4) {
    408          1.1     joerg 			ic->ic_channels[i].ic_freq =
    409          1.1     joerg 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
    410          1.1     joerg 			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
    411          1.1     joerg 		}
    412          1.1     joerg 		for (i = 100; i <= 140; i += 4) {
    413          1.1     joerg 			ic->ic_channels[i].ic_freq =
    414          1.1     joerg 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
    415          1.1     joerg 			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
    416          1.1     joerg 		}
    417          1.1     joerg 		for (i = 149; i <= 165; i += 4) {
    418          1.1     joerg 			ic->ic_channels[i].ic_freq =
    419          1.1     joerg 			    ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
    420          1.1     joerg 			ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A;
    421          1.1     joerg 		}
    422          1.1     joerg 	}
    423          1.1     joerg 
    424          1.1     joerg 	/* set supported .11b and .11g rates */
    425          1.1     joerg 	ic->ic_sup_rates[IEEE80211_MODE_11B] = rum_rateset_11b;
    426          1.1     joerg 	ic->ic_sup_rates[IEEE80211_MODE_11G] = rum_rateset_11g;
    427          1.1     joerg 
    428          1.1     joerg 	/* set supported .11b and .11g channels (1 through 14) */
    429          1.1     joerg 	for (i = 1; i <= 14; i++) {
    430          1.1     joerg 		ic->ic_channels[i].ic_freq =
    431          1.1     joerg 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
    432          1.1     joerg 		ic->ic_channels[i].ic_flags =
    433          1.1     joerg 		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
    434          1.1     joerg 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
    435          1.1     joerg 	}
    436          1.1     joerg 
    437          1.1     joerg 	ifp->if_softc = sc;
    438          1.1     joerg 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    439          1.1     joerg 	ifp->if_init = rum_init;
    440          1.1     joerg 	ifp->if_ioctl = rum_ioctl;
    441          1.1     joerg 	ifp->if_start = rum_start;
    442          1.1     joerg 	ifp->if_watchdog = rum_watchdog;
    443          1.1     joerg 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
    444          1.1     joerg 	IFQ_SET_READY(&ifp->if_snd);
    445          1.1     joerg 	memcpy(ifp->if_xname, USBDEVNAME(sc->sc_dev), IFNAMSIZ);
    446          1.1     joerg 
    447          1.1     joerg 	if_attach(ifp);
    448          1.1     joerg 	ieee80211_ifattach(ic);
    449          1.1     joerg 
    450          1.1     joerg 	/* override state transition machine */
    451          1.1     joerg 	sc->sc_newstate = ic->ic_newstate;
    452          1.1     joerg 	ic->ic_newstate = rum_newstate;
    453          1.1     joerg 	ieee80211_media_init(ic, rum_media_change, ieee80211_media_status);
    454          1.1     joerg 
    455          1.1     joerg #if NBPFILTER > 0
    456          1.1     joerg 	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
    457          1.1     joerg 	    sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, &sc->sc_drvbpf);
    458          1.1     joerg 
    459          1.1     joerg 	sc->sc_rxtap_len = sizeof sc->sc_rxtapu;
    460          1.1     joerg 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
    461          1.1     joerg 	sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
    462          1.1     joerg 
    463          1.1     joerg 	sc->sc_txtap_len = sizeof sc->sc_txtapu;
    464          1.1     joerg 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
    465          1.1     joerg 	sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
    466          1.1     joerg #endif
    467          1.1     joerg 
    468          1.1     joerg 	ieee80211_announce(ic);
    469          1.1     joerg 
    470          1.1     joerg 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
    471          1.1     joerg 	    USBDEV(sc->sc_dev));
    472          1.1     joerg 
    473          1.1     joerg 	USB_ATTACH_SUCCESS_RETURN;
    474          1.1     joerg }
    475          1.1     joerg 
    476          1.1     joerg USB_DETACH(rum)
    477          1.1     joerg {
    478          1.1     joerg 	USB_DETACH_START(rum, sc);
    479          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
    480          1.1     joerg 	struct ifnet *ifp = &sc->sc_if;
    481          1.1     joerg 	int s;
    482          1.1     joerg 
    483          1.1     joerg 	s = splusb();
    484          1.1     joerg 
    485          1.1     joerg 	rum_stop(ifp, 1);
    486          1.1     joerg 	usb_rem_task(sc->sc_udev, &sc->sc_task);
    487          1.1     joerg 	callout_stop(&sc->scan_ch);
    488          1.1     joerg 	callout_stop(&sc->amrr_ch);
    489          1.1     joerg 
    490          1.1     joerg 	if (sc->amrr_xfer != NULL) {
    491          1.1     joerg 		usbd_free_xfer(sc->amrr_xfer);
    492          1.1     joerg 		sc->amrr_xfer = NULL;
    493          1.1     joerg 	}
    494          1.1     joerg 
    495          1.1     joerg 	if (sc->sc_rx_pipeh != NULL) {
    496          1.1     joerg 		usbd_abort_pipe(sc->sc_rx_pipeh);
    497          1.1     joerg 		usbd_close_pipe(sc->sc_rx_pipeh);
    498          1.1     joerg 	}
    499          1.1     joerg 
    500          1.1     joerg 	if (sc->sc_tx_pipeh != NULL) {
    501          1.1     joerg 		usbd_abort_pipe(sc->sc_tx_pipeh);
    502          1.1     joerg 		usbd_close_pipe(sc->sc_tx_pipeh);
    503          1.1     joerg 	}
    504          1.1     joerg 
    505          1.1     joerg 	rum_free_rx_list(sc);
    506          1.1     joerg 	rum_free_tx_list(sc);
    507          1.1     joerg 
    508          1.1     joerg #if NBPFILTER > 0
    509          1.1     joerg 	bpfdetach(ifp);
    510          1.1     joerg #endif
    511          1.1     joerg 	ieee80211_ifdetach(ic);	/* free all nodes */
    512          1.1     joerg 	if_detach(ifp);
    513          1.1     joerg 
    514          1.1     joerg 	splx(s);
    515          1.1     joerg 
    516          1.1     joerg 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
    517          1.1     joerg 	    USBDEV(sc->sc_dev));
    518          1.1     joerg 
    519          1.1     joerg 	return 0;
    520          1.1     joerg }
    521          1.1     joerg 
    522          1.1     joerg Static int
    523          1.1     joerg rum_alloc_tx_list(struct rum_softc *sc)
    524          1.1     joerg {
    525          1.1     joerg 	struct rum_tx_data *data;
    526          1.1     joerg 	int i, error;
    527          1.1     joerg 
    528          1.1     joerg 	sc->tx_queued = 0;
    529          1.1     joerg 
    530          1.1     joerg 	for (i = 0; i < RT2573_TX_LIST_COUNT; i++) {
    531          1.1     joerg 		data = &sc->tx_data[i];
    532          1.1     joerg 
    533          1.1     joerg 		data->sc = sc;
    534          1.1     joerg 
    535          1.1     joerg 		data->xfer = usbd_alloc_xfer(sc->sc_udev);
    536          1.1     joerg 		if (data->xfer == NULL) {
    537          1.1     joerg 			printf("%s: could not allocate tx xfer\n",
    538          1.1     joerg 			    USBDEVNAME(sc->sc_dev));
    539          1.1     joerg 			error = ENOMEM;
    540          1.1     joerg 			goto fail;
    541          1.1     joerg 		}
    542          1.1     joerg 
    543          1.1     joerg 		data->buf = usbd_alloc_buffer(data->xfer,
    544          1.1     joerg 		    RT2573_TX_DESC_SIZE + MCLBYTES);
    545          1.1     joerg 		if (data->buf == NULL) {
    546          1.1     joerg 			printf("%s: could not allocate tx buffer\n",
    547          1.1     joerg 			    USBDEVNAME(sc->sc_dev));
    548          1.1     joerg 			error = ENOMEM;
    549          1.1     joerg 			goto fail;
    550          1.1     joerg 		}
    551          1.1     joerg 
    552          1.1     joerg 		/* clean Tx descriptor */
    553          1.1     joerg 		bzero(data->buf, RT2573_TX_DESC_SIZE);
    554          1.1     joerg 	}
    555          1.1     joerg 
    556          1.1     joerg 	return 0;
    557          1.1     joerg 
    558          1.1     joerg fail:	rum_free_tx_list(sc);
    559          1.1     joerg 	return error;
    560          1.1     joerg }
    561          1.1     joerg 
    562          1.1     joerg Static void
    563          1.1     joerg rum_free_tx_list(struct rum_softc *sc)
    564          1.1     joerg {
    565          1.1     joerg 	struct rum_tx_data *data;
    566          1.1     joerg 	int i;
    567          1.1     joerg 
    568          1.1     joerg 	for (i = 0; i < RT2573_TX_LIST_COUNT; i++) {
    569          1.1     joerg 		data = &sc->tx_data[i];
    570          1.1     joerg 
    571          1.1     joerg 		if (data->xfer != NULL) {
    572          1.1     joerg 			usbd_free_xfer(data->xfer);
    573          1.1     joerg 			data->xfer = NULL;
    574          1.1     joerg 		}
    575          1.1     joerg 
    576          1.1     joerg 		if (data->ni != NULL) {
    577          1.1     joerg 			ieee80211_free_node(data->ni);
    578          1.1     joerg 			data->ni = NULL;
    579          1.1     joerg 		}
    580          1.1     joerg 	}
    581          1.1     joerg }
    582          1.1     joerg 
    583          1.1     joerg Static int
    584          1.1     joerg rum_alloc_rx_list(struct rum_softc *sc)
    585          1.1     joerg {
    586          1.1     joerg 	struct rum_rx_data *data;
    587          1.1     joerg 	int i, error;
    588          1.1     joerg 
    589          1.1     joerg 	for (i = 0; i < RT2573_RX_LIST_COUNT; i++) {
    590          1.1     joerg 		data = &sc->rx_data[i];
    591          1.1     joerg 
    592          1.1     joerg 		data->sc = sc;
    593          1.1     joerg 
    594          1.1     joerg 		data->xfer = usbd_alloc_xfer(sc->sc_udev);
    595          1.1     joerg 		if (data->xfer == NULL) {
    596          1.1     joerg 			printf("%s: could not allocate rx xfer\n",
    597          1.1     joerg 			    USBDEVNAME(sc->sc_dev));
    598          1.1     joerg 			error = ENOMEM;
    599          1.1     joerg 			goto fail;
    600          1.1     joerg 		}
    601          1.1     joerg 
    602          1.1     joerg 		if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) {
    603          1.1     joerg 			printf("%s: could not allocate rx buffer\n",
    604          1.1     joerg 			    USBDEVNAME(sc->sc_dev));
    605          1.1     joerg 			error = ENOMEM;
    606          1.1     joerg 			goto fail;
    607          1.1     joerg 		}
    608          1.1     joerg 
    609          1.1     joerg 		MGETHDR(data->m, M_DONTWAIT, MT_DATA);
    610          1.1     joerg 		if (data->m == NULL) {
    611          1.1     joerg 			printf("%s: could not allocate rx mbuf\n",
    612          1.1     joerg 			    USBDEVNAME(sc->sc_dev));
    613          1.1     joerg 			error = ENOMEM;
    614          1.1     joerg 			goto fail;
    615          1.1     joerg 		}
    616          1.1     joerg 
    617          1.1     joerg 		MCLGET(data->m, M_DONTWAIT);
    618          1.1     joerg 		if (!(data->m->m_flags & M_EXT)) {
    619          1.1     joerg 			printf("%s: could not allocate rx mbuf cluster\n",
    620          1.1     joerg 			    USBDEVNAME(sc->sc_dev));
    621          1.1     joerg 			error = ENOMEM;
    622          1.1     joerg 			goto fail;
    623          1.1     joerg 		}
    624          1.1     joerg 
    625          1.1     joerg 		data->buf = mtod(data->m, uint8_t *);
    626          1.1     joerg 	}
    627          1.1     joerg 
    628          1.1     joerg 	return 0;
    629          1.1     joerg 
    630          1.1     joerg fail:	rum_free_tx_list(sc);
    631          1.1     joerg 	return error;
    632          1.1     joerg }
    633          1.1     joerg 
    634          1.1     joerg Static void
    635          1.1     joerg rum_free_rx_list(struct rum_softc *sc)
    636          1.1     joerg {
    637          1.1     joerg 	struct rum_rx_data *data;
    638          1.1     joerg 	int i;
    639          1.1     joerg 
    640          1.1     joerg 	for (i = 0; i < RT2573_RX_LIST_COUNT; i++) {
    641          1.1     joerg 		data = &sc->rx_data[i];
    642          1.1     joerg 
    643          1.1     joerg 		if (data->xfer != NULL) {
    644          1.1     joerg 			usbd_free_xfer(data->xfer);
    645          1.1     joerg 			data->xfer = NULL;
    646          1.1     joerg 		}
    647          1.1     joerg 
    648          1.1     joerg 		if (data->m != NULL) {
    649          1.1     joerg 			m_freem(data->m);
    650          1.1     joerg 			data->m = NULL;
    651          1.1     joerg 		}
    652          1.1     joerg 	}
    653          1.1     joerg }
    654          1.1     joerg 
    655          1.1     joerg Static int
    656          1.1     joerg rum_media_change(struct ifnet *ifp)
    657          1.1     joerg {
    658          1.1     joerg 	int error;
    659          1.1     joerg 
    660          1.1     joerg 	error = ieee80211_media_change(ifp);
    661          1.1     joerg 	if (error != ENETRESET)
    662          1.1     joerg 		return error;
    663          1.1     joerg 
    664          1.1     joerg 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
    665          1.1     joerg 		rum_init(ifp);
    666          1.1     joerg 
    667          1.1     joerg 	return 0;
    668          1.1     joerg }
    669          1.1     joerg 
    670          1.1     joerg /*
    671          1.1     joerg  * This function is called periodically (every 200ms) during scanning to
    672          1.1     joerg  * switch from one channel to another.
    673          1.1     joerg  */
    674          1.1     joerg Static void
    675          1.1     joerg rum_next_scan(void *arg)
    676          1.1     joerg {
    677          1.1     joerg 	struct rum_softc *sc = arg;
    678          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
    679          1.1     joerg 
    680          1.1     joerg 	if (ic->ic_state == IEEE80211_S_SCAN)
    681          1.1     joerg 		ieee80211_next_scan(ic);
    682          1.1     joerg }
    683          1.1     joerg 
    684          1.1     joerg Static void
    685          1.1     joerg rum_task(void *arg)
    686          1.1     joerg {
    687          1.1     joerg 	struct rum_softc *sc = arg;
    688          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
    689          1.1     joerg 	enum ieee80211_state ostate;
    690          1.1     joerg 	struct ieee80211_node *ni;
    691          1.1     joerg 	uint32_t tmp;
    692          1.1     joerg 
    693          1.1     joerg 	ostate = ic->ic_state;
    694          1.1     joerg 
    695          1.1     joerg 	switch (sc->sc_state) {
    696          1.1     joerg 	case IEEE80211_S_INIT:
    697          1.1     joerg 		if (ostate == IEEE80211_S_RUN) {
    698          1.1     joerg 			/* abort TSF synchronization */
    699          1.1     joerg 			tmp = rum_read(sc, RT2573_TXRX_CSR9);
    700          1.1     joerg 			rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
    701          1.1     joerg 		}
    702          1.1     joerg 		break;
    703          1.1     joerg 
    704          1.1     joerg 	case IEEE80211_S_SCAN:
    705          1.1     joerg 		rum_set_chan(sc, ic->ic_curchan);
    706          1.1     joerg 		callout_reset(&sc->scan_ch, hz / 5, rum_next_scan, sc);
    707          1.1     joerg 		break;
    708          1.1     joerg 
    709          1.1     joerg 	case IEEE80211_S_AUTH:
    710          1.1     joerg 		rum_set_chan(sc, ic->ic_curchan);
    711          1.1     joerg 		break;
    712          1.1     joerg 
    713          1.1     joerg 	case IEEE80211_S_ASSOC:
    714          1.1     joerg 		rum_set_chan(sc, ic->ic_curchan);
    715          1.1     joerg 		break;
    716          1.1     joerg 
    717          1.1     joerg 	case IEEE80211_S_RUN:
    718          1.1     joerg 		rum_set_chan(sc, ic->ic_curchan);
    719          1.1     joerg 
    720          1.1     joerg 		ni = ic->ic_bss;
    721          1.1     joerg 
    722          1.1     joerg 		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
    723          1.1     joerg 			rum_update_slot(sc);
    724          1.1     joerg 			rum_enable_mrr(sc);
    725          1.1     joerg 			rum_set_txpreamble(sc);
    726          1.1     joerg 			rum_set_basicrates(sc);
    727          1.1     joerg 			rum_set_bssid(sc, ni->ni_bssid);
    728          1.1     joerg 		}
    729          1.1     joerg 
    730          1.1     joerg 		if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
    731          1.1     joerg 		    ic->ic_opmode == IEEE80211_M_IBSS)
    732          1.1     joerg 			rum_prepare_beacon(sc);
    733          1.1     joerg 
    734          1.1     joerg 		if (ic->ic_opmode != IEEE80211_M_MONITOR)
    735          1.1     joerg 			rum_enable_tsf_sync(sc);
    736          1.1     joerg 
    737          1.1     joerg 		/* enable automatic rate adaptation in STA mode */
    738          1.1     joerg 		if (ic->ic_opmode == IEEE80211_M_STA &&
    739          1.1     joerg 		    ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE)
    740          1.1     joerg 			rum_amrr_start(sc, ni);
    741          1.1     joerg 
    742          1.1     joerg 		break;
    743          1.1     joerg 	}
    744          1.1     joerg 
    745          1.1     joerg 	sc->sc_newstate(ic, sc->sc_state, -1);
    746          1.1     joerg }
    747          1.1     joerg 
    748          1.1     joerg Static int
    749          1.1     joerg rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
    750          1.1     joerg {
    751          1.1     joerg 	struct rum_softc *sc = ic->ic_ifp->if_softc;
    752          1.1     joerg 
    753          1.1     joerg 	usb_rem_task(sc->sc_udev, &sc->sc_task);
    754          1.1     joerg 	callout_stop(&sc->scan_ch);
    755          1.1     joerg 	callout_stop(&sc->amrr_ch);
    756          1.1     joerg 
    757          1.1     joerg 	/* do it in a process context */
    758          1.1     joerg 	sc->sc_state = nstate;
    759          1.1     joerg 	usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
    760          1.1     joerg 
    761          1.1     joerg 	return 0;
    762          1.1     joerg }
    763          1.1     joerg 
    764          1.1     joerg /* quickly determine if a given rate is CCK or OFDM */
    765          1.1     joerg #define RUM_RATE_IS_OFDM(rate)	((rate) >= 12 && (rate) != 22)
    766          1.1     joerg 
    767          1.1     joerg #define RUM_ACK_SIZE	14	/* 10 + 4(FCS) */
    768          1.1     joerg #define RUM_CTS_SIZE	14	/* 10 + 4(FCS) */
    769          1.1     joerg 
    770          1.1     joerg Static void
    771          1.1     joerg rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
    772          1.1     joerg {
    773          1.1     joerg 	struct rum_tx_data *data = priv;
    774          1.1     joerg 	struct rum_softc *sc = data->sc;
    775          1.1     joerg 	struct ifnet *ifp = &sc->sc_if;
    776          1.1     joerg 	int s;
    777          1.1     joerg 
    778          1.1     joerg 	if (status != USBD_NORMAL_COMPLETION) {
    779          1.1     joerg 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
    780          1.1     joerg 			return;
    781          1.1     joerg 
    782          1.1     joerg 		printf("%s: could not transmit buffer: %s\n",
    783          1.1     joerg 		    USBDEVNAME(sc->sc_dev), usbd_errstr(status));
    784          1.1     joerg 
    785          1.1     joerg 		if (status == USBD_STALLED)
    786          1.1     joerg 			usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh);
    787          1.1     joerg 
    788          1.1     joerg 		ifp->if_oerrors++;
    789          1.1     joerg 		return;
    790          1.1     joerg 	}
    791          1.1     joerg 
    792          1.1     joerg 	s = splnet();
    793          1.1     joerg 
    794          1.1     joerg 	m_freem(data->m);
    795          1.1     joerg 	data->m = NULL;
    796          1.1     joerg 	ieee80211_free_node(data->ni);
    797          1.1     joerg 	data->ni = NULL;
    798          1.1     joerg 
    799          1.1     joerg 	sc->tx_queued--;
    800          1.1     joerg 	ifp->if_opackets++;
    801          1.1     joerg 
    802          1.1     joerg 	DPRINTFN(10, ("tx done\n"));
    803          1.1     joerg 
    804          1.1     joerg 	sc->sc_tx_timer = 0;
    805          1.1     joerg 	ifp->if_flags &= ~IFF_OACTIVE;
    806          1.1     joerg 	rum_start(ifp);
    807          1.1     joerg 
    808          1.1     joerg 	splx(s);
    809          1.1     joerg }
    810          1.1     joerg 
    811          1.1     joerg Static void
    812          1.1     joerg rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
    813          1.1     joerg {
    814          1.1     joerg 	struct rum_rx_data *data = priv;
    815          1.1     joerg 	struct rum_softc *sc = data->sc;
    816          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
    817          1.1     joerg 	struct ifnet *ifp = &sc->sc_if;
    818          1.1     joerg 	struct rum_rx_desc *desc;
    819          1.1     joerg 	struct ieee80211_frame *wh;
    820          1.1     joerg 	struct ieee80211_node *ni;
    821          1.1     joerg 	struct mbuf *mnew, *m;
    822          1.1     joerg 	int s, len;
    823          1.1     joerg 
    824          1.1     joerg 	if (status != USBD_NORMAL_COMPLETION) {
    825          1.1     joerg 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
    826          1.1     joerg 			return;
    827          1.1     joerg 
    828          1.1     joerg 		if (status == USBD_STALLED)
    829          1.1     joerg 			usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
    830          1.1     joerg 		goto skip;
    831          1.1     joerg 	}
    832          1.1     joerg 
    833          1.1     joerg 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
    834          1.1     joerg 
    835          1.1     joerg 	if (len < RT2573_RX_DESC_SIZE + sizeof (struct ieee80211_frame_min)) {
    836          1.1     joerg 		DPRINTF(("%s: xfer too short %d\n", USBDEVNAME(sc->sc_dev),
    837          1.1     joerg 		    len));
    838          1.1     joerg 		ifp->if_ierrors++;
    839          1.1     joerg 		goto skip;
    840          1.1     joerg 	}
    841          1.1     joerg 
    842          1.1     joerg 	desc = (struct rum_rx_desc *)data->buf;
    843          1.1     joerg 
    844          1.1     joerg 	if (le32toh(desc->flags) & RT2573_RX_CRC_ERROR) {
    845          1.1     joerg 		/*
    846          1.1     joerg 		 * This should not happen since we did not request to receive
    847          1.1     joerg 		 * those frames when we filled RT2573_TXRX_CSR0.
    848          1.1     joerg 		 */
    849          1.1     joerg 		DPRINTFN(5, ("CRC error\n"));
    850          1.1     joerg 		ifp->if_ierrors++;
    851          1.1     joerg 		goto skip;
    852          1.1     joerg 	}
    853          1.1     joerg 
    854          1.1     joerg 	MGETHDR(mnew, M_DONTWAIT, MT_DATA);
    855          1.1     joerg 	if (mnew == NULL) {
    856          1.1     joerg 		printf("%s: could not allocate rx mbuf\n",
    857          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
    858          1.1     joerg 		ifp->if_ierrors++;
    859          1.1     joerg 		goto skip;
    860          1.1     joerg 	}
    861          1.1     joerg 
    862          1.1     joerg 	MCLGET(mnew, M_DONTWAIT);
    863          1.1     joerg 	if (!(mnew->m_flags & M_EXT)) {
    864          1.1     joerg 		printf("%s: could not allocate rx mbuf cluster\n",
    865          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
    866          1.1     joerg 		m_freem(mnew);
    867          1.1     joerg 		ifp->if_ierrors++;
    868          1.1     joerg 		goto skip;
    869          1.1     joerg 	}
    870          1.1     joerg 
    871          1.1     joerg 	m = data->m;
    872          1.1     joerg 	data->m = mnew;
    873          1.1     joerg 	data->buf = mtod(data->m, uint8_t *);
    874          1.1     joerg 
    875          1.1     joerg 	/* finalize mbuf */
    876          1.1     joerg 	m->m_pkthdr.rcvif = ifp;
    877          1.1     joerg 	m->m_data = (caddr_t)(desc + 1);
    878          1.1     joerg 	m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff;
    879          1.1     joerg 
    880          1.1     joerg 	s = splnet();
    881          1.1     joerg 
    882          1.1     joerg #if NBPFILTER > 0
    883          1.1     joerg 	if (sc->sc_drvbpf != NULL) {
    884          1.1     joerg 		struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
    885          1.1     joerg 
    886          1.1     joerg 		tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
    887          1.1     joerg 		tap->wr_rate = rum_rxrate(desc);
    888          1.1     joerg 		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
    889          1.1     joerg 		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
    890          1.1     joerg 		tap->wr_antenna = sc->rx_ant;
    891          1.1     joerg 		tap->wr_antsignal = desc->rssi;
    892          1.1     joerg 
    893          1.1     joerg 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
    894          1.1     joerg 	}
    895          1.1     joerg #endif
    896          1.1     joerg 
    897          1.1     joerg 	wh = mtod(m, struct ieee80211_frame *);
    898          1.1     joerg 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
    899          1.1     joerg 
    900          1.1     joerg 	/* send the frame to the 802.11 layer */
    901          1.1     joerg 	ieee80211_input(ic, m, ni, desc->rssi, 0);
    902          1.1     joerg 
    903          1.1     joerg 	/* node is no longer needed */
    904          1.1     joerg 	ieee80211_free_node(ni);
    905          1.1     joerg 
    906          1.1     joerg 	splx(s);
    907          1.1     joerg 
    908          1.1     joerg 	DPRINTFN(15, ("rx done\n"));
    909          1.1     joerg 
    910          1.1     joerg skip:	/* setup a new transfer */
    911          1.1     joerg 	usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES,
    912          1.1     joerg 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof);
    913          1.1     joerg 	usbd_transfer(xfer);
    914          1.1     joerg }
    915          1.1     joerg 
    916          1.1     joerg /*
    917          1.1     joerg  * This function is only used by the Rx radiotap code. It returns the rate at
    918          1.1     joerg  * which a given frame was received.
    919          1.1     joerg  */
    920          1.1     joerg #if NBPFILTER > 0
    921          1.1     joerg Static uint8_t
    922          1.1     joerg rum_rxrate(struct rum_rx_desc *desc)
    923          1.1     joerg {
    924          1.1     joerg 	if (le32toh(desc->flags) & RT2573_RX_OFDM) {
    925          1.1     joerg 		/* reverse function of rum_plcp_signal */
    926          1.1     joerg 		switch (desc->rate) {
    927          1.1     joerg 		case 0xb:	return 12;
    928          1.1     joerg 		case 0xf:	return 18;
    929          1.1     joerg 		case 0xa:	return 24;
    930          1.1     joerg 		case 0xe:	return 36;
    931          1.1     joerg 		case 0x9:	return 48;
    932          1.1     joerg 		case 0xd:	return 72;
    933          1.1     joerg 		case 0x8:	return 96;
    934          1.1     joerg 		case 0xc:	return 108;
    935          1.1     joerg 		}
    936          1.1     joerg 	} else {
    937          1.1     joerg 		if (desc->rate == 10)
    938          1.1     joerg 			return 2;
    939          1.1     joerg 		if (desc->rate == 20)
    940          1.1     joerg 			return 4;
    941          1.1     joerg 		if (desc->rate == 55)
    942          1.1     joerg 			return 11;
    943          1.1     joerg 		if (desc->rate == 110)
    944          1.1     joerg 			return 22;
    945          1.1     joerg 	}
    946          1.1     joerg 	return 2;	/* should not get there */
    947          1.1     joerg }
    948          1.1     joerg #endif
    949          1.1     joerg 
    950          1.1     joerg /*
    951          1.1     joerg  * Return the expected ack rate for a frame transmitted at rate `rate'.
    952          1.1     joerg  * XXX: this should depend on the destination node basic rate set.
    953          1.1     joerg  */
    954          1.1     joerg Static int
    955          1.1     joerg rum_ack_rate(struct ieee80211com *ic, int rate)
    956          1.1     joerg {
    957          1.1     joerg 	switch (rate) {
    958          1.1     joerg 	/* CCK rates */
    959          1.1     joerg 	case 2:
    960          1.1     joerg 		return 2;
    961          1.1     joerg 	case 4:
    962          1.1     joerg 	case 11:
    963          1.1     joerg 	case 22:
    964          1.1     joerg 		return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
    965          1.1     joerg 
    966          1.1     joerg 	/* OFDM rates */
    967          1.1     joerg 	case 12:
    968          1.1     joerg 	case 18:
    969          1.1     joerg 		return 12;
    970          1.1     joerg 	case 24:
    971          1.1     joerg 	case 36:
    972          1.1     joerg 		return 24;
    973          1.1     joerg 	case 48:
    974          1.1     joerg 	case 72:
    975          1.1     joerg 	case 96:
    976          1.1     joerg 	case 108:
    977          1.1     joerg 		return 48;
    978          1.1     joerg 	}
    979          1.1     joerg 
    980          1.1     joerg 	/* default to 1Mbps */
    981          1.1     joerg 	return 2;
    982          1.1     joerg }
    983          1.1     joerg 
    984          1.1     joerg /*
    985          1.1     joerg  * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
    986          1.1     joerg  * The function automatically determines the operating mode depending on the
    987          1.1     joerg  * given rate. `flags' indicates whether short preamble is in use or not.
    988          1.1     joerg  */
    989          1.1     joerg Static uint16_t
    990          1.1     joerg rum_txtime(int len, int rate, uint32_t flags)
    991          1.1     joerg {
    992          1.1     joerg 	uint16_t txtime;
    993          1.1     joerg 
    994          1.1     joerg 	if (RUM_RATE_IS_OFDM(rate)) {
    995          1.1     joerg 		/* IEEE Std 802.11a-1999, pp. 37 */
    996          1.1     joerg 		txtime = (8 + 4 * len + 3 + rate - 1) / rate;
    997          1.1     joerg 		txtime = 16 + 4 + 4 * txtime + 6;
    998          1.1     joerg 	} else {
    999          1.1     joerg 		/* IEEE Std 802.11b-1999, pp. 28 */
   1000          1.1     joerg 		txtime = (16 * len + rate - 1) / rate;
   1001          1.1     joerg 		if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
   1002          1.1     joerg 			txtime +=  72 + 24;
   1003          1.1     joerg 		else
   1004          1.1     joerg 			txtime += 144 + 48;
   1005          1.1     joerg 	}
   1006          1.1     joerg 	return txtime;
   1007          1.1     joerg }
   1008          1.1     joerg 
   1009          1.1     joerg Static uint8_t
   1010          1.1     joerg rum_plcp_signal(int rate)
   1011          1.1     joerg {
   1012          1.1     joerg 	switch (rate) {
   1013          1.1     joerg 	/* CCK rates (returned values are device-dependent) */
   1014          1.1     joerg 	case 2:		return 0x0;
   1015          1.1     joerg 	case 4:		return 0x1;
   1016          1.1     joerg 	case 11:	return 0x2;
   1017          1.1     joerg 	case 22:	return 0x3;
   1018          1.1     joerg 
   1019          1.1     joerg 	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
   1020          1.1     joerg 	case 12:	return 0xb;
   1021          1.1     joerg 	case 18:	return 0xf;
   1022          1.1     joerg 	case 24:	return 0xa;
   1023          1.1     joerg 	case 36:	return 0xe;
   1024          1.1     joerg 	case 48:	return 0x9;
   1025          1.1     joerg 	case 72:	return 0xd;
   1026          1.1     joerg 	case 96:	return 0x8;
   1027          1.1     joerg 	case 108:	return 0xc;
   1028          1.1     joerg 
   1029          1.1     joerg 	/* unsupported rates (should not get there) */
   1030          1.1     joerg 	default:	return 0xff;
   1031          1.1     joerg 	}
   1032          1.1     joerg }
   1033          1.1     joerg 
   1034          1.1     joerg Static void
   1035          1.1     joerg rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
   1036          1.1     joerg     uint32_t flags, uint16_t xflags, int len, int rate)
   1037          1.1     joerg {
   1038          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1039          1.1     joerg 	uint16_t plcp_length;
   1040          1.1     joerg 	int remainder;
   1041          1.1     joerg 
   1042          1.1     joerg 	desc->flags = htole32(flags);
   1043          1.1     joerg 	desc->flags |= htole32(RT2573_TX_VALID);
   1044          1.1     joerg 	desc->flags |= htole32(len << 16);
   1045          1.1     joerg 
   1046          1.1     joerg 	desc->xflags = htole16(xflags);
   1047          1.1     joerg 
   1048          1.1     joerg 	desc->wme = htole16(
   1049          1.1     joerg 	    RT2573_QID(0) |
   1050          1.1     joerg 	    RT2573_AIFSN(2) |
   1051          1.1     joerg 	    RT2573_LOGCWMIN(4) |
   1052          1.1     joerg 	    RT2573_LOGCWMAX(10));
   1053          1.1     joerg 
   1054          1.1     joerg 	/* setup PLCP fields */
   1055          1.1     joerg 	desc->plcp_signal  = rum_plcp_signal(rate);
   1056          1.1     joerg 	desc->plcp_service = 4;
   1057          1.1     joerg 
   1058          1.1     joerg 	len += IEEE80211_CRC_LEN;
   1059          1.1     joerg 	if (RUM_RATE_IS_OFDM(rate)) {
   1060          1.1     joerg 		desc->flags |= htole32(RT2573_TX_OFDM);
   1061          1.1     joerg 
   1062          1.1     joerg 		plcp_length = len & 0xfff;
   1063          1.1     joerg 		desc->plcp_length_hi = plcp_length >> 6;
   1064          1.1     joerg 		desc->plcp_length_lo = plcp_length & 0x3f;
   1065          1.1     joerg 	} else {
   1066          1.1     joerg 		plcp_length = (16 * len + rate - 1) / rate;
   1067          1.1     joerg 		if (rate == 22) {
   1068          1.1     joerg 			remainder = (16 * len) % 22;
   1069          1.1     joerg 			if (remainder != 0 && remainder < 7)
   1070          1.1     joerg 				desc->plcp_service |= RT2573_PLCP_LENGEXT;
   1071          1.1     joerg 		}
   1072          1.1     joerg 		desc->plcp_length_hi = plcp_length >> 8;
   1073          1.1     joerg 		desc->plcp_length_lo = plcp_length & 0xff;
   1074          1.1     joerg 
   1075          1.1     joerg 		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
   1076          1.1     joerg 			desc->plcp_signal |= 0x08;
   1077          1.1     joerg 	}
   1078          1.1     joerg }
   1079          1.1     joerg 
   1080          1.1     joerg #define RUM_TX_TIMEOUT	5000
   1081          1.1     joerg 
   1082          1.1     joerg Static int
   1083          1.1     joerg rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
   1084          1.1     joerg {
   1085          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1086          1.1     joerg 	struct rum_tx_desc *desc;
   1087          1.1     joerg 	struct rum_tx_data *data;
   1088          1.1     joerg 	struct ieee80211_frame *wh;
   1089          1.1     joerg 	uint32_t flags = 0;
   1090          1.1     joerg 	uint16_t dur;
   1091          1.1     joerg 	usbd_status error;
   1092          1.1     joerg 	int xferlen, rate;
   1093          1.1     joerg 
   1094          1.1     joerg 	data = &sc->tx_data[0];
   1095          1.1     joerg 	desc = (struct rum_tx_desc *)data->buf;
   1096          1.1     joerg 
   1097          1.1     joerg 	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
   1098          1.1     joerg 
   1099          1.1     joerg 	data->m = m0;
   1100          1.1     joerg 	data->ni = ni;
   1101          1.1     joerg 
   1102          1.1     joerg 	wh = mtod(m0, struct ieee80211_frame *);
   1103          1.1     joerg 
   1104          1.1     joerg 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
   1105          1.1     joerg 		flags |= RT2573_TX_ACK;
   1106          1.1     joerg 
   1107          1.1     joerg 		dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
   1108          1.1     joerg 		    ic->ic_flags) + sc->sifs;
   1109          1.1     joerg 		*(uint16_t *)wh->i_dur = htole16(dur);
   1110          1.1     joerg 
   1111          1.1     joerg 		/* tell hardware to set timestamp in probe responses */
   1112          1.1     joerg 		if ((wh->i_fc[0] &
   1113          1.1     joerg 		    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
   1114          1.1     joerg 		    (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
   1115          1.1     joerg 			flags |= RT2573_TX_TIMESTAMP;
   1116          1.1     joerg 	}
   1117          1.1     joerg 
   1118          1.1     joerg #if NBPFILTER > 0
   1119          1.1     joerg 	if (sc->sc_drvbpf != NULL) {
   1120          1.1     joerg 		struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
   1121          1.1     joerg 
   1122          1.1     joerg 		tap->wt_flags = 0;
   1123          1.1     joerg 		tap->wt_rate = rate;
   1124          1.1     joerg 		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
   1125          1.1     joerg 		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
   1126          1.1     joerg 		tap->wt_antenna = sc->tx_ant;
   1127          1.1     joerg 
   1128          1.1     joerg 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
   1129          1.1     joerg 	}
   1130          1.1     joerg #endif
   1131          1.1     joerg 
   1132          1.1     joerg 	m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
   1133          1.1     joerg 	rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate);
   1134          1.1     joerg 
   1135          1.1     joerg 	/* align end on a 4-bytes boundary */
   1136          1.1     joerg 	xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
   1137          1.1     joerg 
   1138          1.1     joerg 	/*
   1139          1.1     joerg 	 * No space left in the last URB to store the extra 4 bytes, force
   1140          1.1     joerg 	 * sending of another URB.
   1141          1.1     joerg 	 */
   1142          1.1     joerg 	if ((xferlen % 64) == 0)
   1143          1.1     joerg 		xferlen += 4;
   1144          1.1     joerg 
   1145      1.3.2.2       jdc 	DPRINTFN(10, ("sending msg frame len=%zu rate=%u xfer len=%u\n",
   1146      1.3.2.2       jdc 	    (size_t)m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, rate, xferlen));
   1147          1.1     joerg 
   1148          1.1     joerg 	usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
   1149          1.1     joerg 	    USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
   1150          1.1     joerg 
   1151          1.1     joerg 	error = usbd_transfer(data->xfer);
   1152          1.1     joerg 	if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
   1153          1.1     joerg 		m_freem(m0);
   1154          1.1     joerg 		return error;
   1155          1.1     joerg 	}
   1156          1.1     joerg 
   1157          1.1     joerg 	sc->tx_queued++;
   1158          1.1     joerg 
   1159          1.1     joerg 	return 0;
   1160          1.1     joerg }
   1161          1.1     joerg 
   1162          1.1     joerg Static int
   1163          1.1     joerg rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
   1164          1.1     joerg {
   1165          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1166          1.1     joerg 	struct rum_tx_desc *desc;
   1167          1.1     joerg 	struct rum_tx_data *data;
   1168          1.1     joerg 	struct ieee80211_frame *wh;
   1169          1.1     joerg 	struct ieee80211_key *k;
   1170          1.1     joerg 	uint32_t flags = 0;
   1171          1.1     joerg 	uint16_t dur;
   1172          1.1     joerg 	usbd_status error;
   1173          1.1     joerg 	int xferlen, rate;
   1174          1.1     joerg 
   1175          1.1     joerg 	wh = mtod(m0, struct ieee80211_frame *);
   1176          1.1     joerg 
   1177          1.1     joerg 	if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
   1178          1.1     joerg 		rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate];
   1179          1.1     joerg 	else
   1180          1.1     joerg 		rate = ni->ni_rates.rs_rates[ni->ni_txrate];
   1181          1.1     joerg 	rate &= IEEE80211_RATE_VAL;
   1182          1.1     joerg 
   1183          1.1     joerg 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
   1184          1.1     joerg 		k = ieee80211_crypto_encap(ic, ni, m0);
   1185          1.1     joerg 		if (k == NULL) {
   1186          1.1     joerg 			m_freem(m0);
   1187          1.1     joerg 			return ENOBUFS;
   1188          1.1     joerg 		}
   1189          1.1     joerg 
   1190          1.1     joerg 		/* packet header may have moved, reset our local pointer */
   1191          1.1     joerg 		wh = mtod(m0, struct ieee80211_frame *);
   1192          1.1     joerg 	}
   1193          1.1     joerg 
   1194          1.1     joerg 	data = &sc->tx_data[0];
   1195          1.1     joerg 	desc = (struct rum_tx_desc *)data->buf;
   1196          1.1     joerg 
   1197          1.1     joerg 	data->m = m0;
   1198          1.1     joerg 	data->ni = ni;
   1199          1.1     joerg 
   1200          1.1     joerg 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
   1201          1.1     joerg 		flags |= RT2573_TX_ACK;
   1202          1.1     joerg 
   1203          1.1     joerg 		dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate),
   1204          1.1     joerg 		    ic->ic_flags) + sc->sifs;
   1205          1.1     joerg 		*(uint16_t *)wh->i_dur = htole16(dur);
   1206          1.1     joerg 	}
   1207          1.1     joerg 
   1208          1.1     joerg #if NBPFILTER > 0
   1209          1.1     joerg 	if (sc->sc_drvbpf != NULL) {
   1210          1.1     joerg 		struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
   1211          1.1     joerg 
   1212          1.1     joerg 		tap->wt_flags = 0;
   1213          1.1     joerg 		tap->wt_rate = rate;
   1214          1.1     joerg 		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
   1215          1.1     joerg 		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
   1216          1.1     joerg 		tap->wt_antenna = sc->tx_ant;
   1217          1.1     joerg 
   1218          1.1     joerg 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
   1219          1.1     joerg 	}
   1220          1.1     joerg #endif
   1221          1.1     joerg 
   1222          1.1     joerg 	m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE);
   1223          1.1     joerg 	rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate);
   1224          1.1     joerg 
   1225          1.1     joerg 	/* align end on a 4-bytes boundary */
   1226          1.1     joerg 	xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3;
   1227          1.1     joerg 
   1228          1.1     joerg 	/*
   1229          1.1     joerg 	 * No space left in the last URB to store the extra 4 bytes, force
   1230          1.1     joerg 	 * sending of another URB.
   1231          1.1     joerg 	 */
   1232          1.1     joerg 	if ((xferlen % 64) == 0)
   1233          1.1     joerg 		xferlen += 4;
   1234          1.1     joerg 
   1235      1.3.2.2       jdc 	DPRINTFN(10, ("sending data frame len=%zu rate=%u xfer len=%u\n",
   1236      1.3.2.2       jdc 	    (size_t)m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, rate, xferlen));
   1237          1.1     joerg 
   1238          1.1     joerg 	usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
   1239          1.1     joerg 	    USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
   1240          1.1     joerg 
   1241          1.1     joerg 	error = usbd_transfer(data->xfer);
   1242          1.1     joerg 	if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
   1243          1.1     joerg 		m_freem(m0);
   1244          1.1     joerg 		return error;
   1245          1.1     joerg 	}
   1246          1.1     joerg 
   1247          1.1     joerg 	sc->tx_queued++;
   1248          1.1     joerg 
   1249          1.1     joerg 	return 0;
   1250          1.1     joerg }
   1251          1.1     joerg 
   1252          1.1     joerg Static void
   1253          1.1     joerg rum_start(struct ifnet *ifp)
   1254          1.1     joerg {
   1255          1.1     joerg 	struct rum_softc *sc = ifp->if_softc;
   1256          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1257          1.1     joerg 	struct ether_header *eh;
   1258          1.1     joerg 	struct ieee80211_node *ni;
   1259          1.1     joerg 	struct mbuf *m0;
   1260          1.1     joerg 
   1261          1.1     joerg 	for (;;) {
   1262          1.1     joerg 		IF_POLL(&ic->ic_mgtq, m0);
   1263          1.1     joerg 		if (m0 != NULL) {
   1264          1.1     joerg 			if (sc->tx_queued >= RT2573_TX_LIST_COUNT) {
   1265          1.1     joerg 				ifp->if_flags |= IFF_OACTIVE;
   1266          1.1     joerg 				break;
   1267          1.1     joerg 			}
   1268          1.1     joerg 			IF_DEQUEUE(&ic->ic_mgtq, m0);
   1269          1.1     joerg 
   1270          1.1     joerg 			ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
   1271          1.1     joerg 			m0->m_pkthdr.rcvif = NULL;
   1272          1.1     joerg #if NBPFILTER > 0
   1273          1.1     joerg 			if (ic->ic_rawbpf != NULL)
   1274          1.1     joerg 				bpf_mtap(ic->ic_rawbpf, m0);
   1275          1.1     joerg #endif
   1276          1.1     joerg 			if (rum_tx_mgt(sc, m0, ni) != 0)
   1277          1.1     joerg 				break;
   1278          1.1     joerg 
   1279          1.1     joerg 		} else {
   1280          1.1     joerg 			if (ic->ic_state != IEEE80211_S_RUN)
   1281          1.1     joerg 				break;
   1282          1.1     joerg 			IFQ_POLL(&ifp->if_snd, m0);
   1283          1.1     joerg 			if (m0 == NULL)
   1284          1.1     joerg 				break;
   1285          1.1     joerg 			if (sc->tx_queued >= RT2573_TX_LIST_COUNT) {
   1286          1.1     joerg 				ifp->if_flags |= IFF_OACTIVE;
   1287          1.1     joerg 				break;
   1288          1.1     joerg 			}
   1289          1.1     joerg 			IFQ_DEQUEUE(&ifp->if_snd, m0);
   1290          1.1     joerg 			if (m0->m_len < sizeof(struct ether_header) &&
   1291          1.1     joerg 			    !(m0 = m_pullup(m0, sizeof(struct ether_header))))
   1292          1.1     joerg 				continue;
   1293          1.1     joerg 
   1294          1.1     joerg 			eh = mtod(m0, struct ether_header *);
   1295          1.1     joerg 			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   1296          1.1     joerg 			if (ni == NULL) {
   1297          1.1     joerg 				m_freem(m0);
   1298          1.1     joerg 				continue;
   1299          1.1     joerg 			}
   1300          1.1     joerg #if NBPFILTER > 0
   1301          1.1     joerg 			if (ifp->if_bpf != NULL)
   1302          1.1     joerg 				bpf_mtap(ifp->if_bpf, m0);
   1303          1.1     joerg #endif
   1304          1.1     joerg 			m0 = ieee80211_encap(ic, m0, ni);
   1305          1.1     joerg 			if (m0 == NULL) {
   1306          1.1     joerg 				ieee80211_free_node(ni);
   1307          1.1     joerg 				continue;
   1308          1.1     joerg 			}
   1309          1.1     joerg #if NBPFILTER > 0
   1310          1.1     joerg 			if (ic->ic_rawbpf != NULL)
   1311          1.1     joerg 				bpf_mtap(ic->ic_rawbpf, m0);
   1312          1.1     joerg #endif
   1313          1.1     joerg 			if (rum_tx_data(sc, m0, ni) != 0) {
   1314          1.1     joerg 				ieee80211_free_node(ni);
   1315          1.1     joerg 				ifp->if_oerrors++;
   1316          1.1     joerg 				break;
   1317          1.1     joerg 			}
   1318          1.1     joerg 		}
   1319          1.1     joerg 
   1320          1.1     joerg 		sc->sc_tx_timer = 5;
   1321          1.1     joerg 		ifp->if_timer = 1;
   1322          1.1     joerg 	}
   1323          1.1     joerg }
   1324          1.1     joerg 
   1325          1.1     joerg Static void
   1326          1.1     joerg rum_watchdog(struct ifnet *ifp)
   1327          1.1     joerg {
   1328          1.1     joerg 	struct rum_softc *sc = ifp->if_softc;
   1329          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1330          1.1     joerg 
   1331          1.1     joerg 	ifp->if_timer = 0;
   1332          1.1     joerg 
   1333          1.1     joerg 	if (sc->sc_tx_timer > 0) {
   1334          1.1     joerg 		if (--sc->sc_tx_timer == 0) {
   1335          1.1     joerg 			printf("%s: device timeout\n", USBDEVNAME(sc->sc_dev));
   1336          1.1     joerg 			/*rum_init(ifp); XXX needs a process context! */
   1337          1.1     joerg 			ifp->if_oerrors++;
   1338          1.1     joerg 			return;
   1339          1.1     joerg 		}
   1340          1.1     joerg 		ifp->if_timer = 1;
   1341          1.1     joerg 	}
   1342          1.1     joerg 
   1343          1.1     joerg 	ieee80211_watchdog(ic);
   1344          1.1     joerg }
   1345          1.1     joerg 
   1346          1.1     joerg Static int
   1347          1.1     joerg rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
   1348          1.1     joerg {
   1349          1.1     joerg 	struct rum_softc *sc = ifp->if_softc;
   1350          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1351          1.1     joerg 	int s, error = 0;
   1352          1.1     joerg 
   1353          1.1     joerg 	s = splnet();
   1354          1.1     joerg 
   1355          1.1     joerg 	switch (cmd) {
   1356          1.1     joerg 	case SIOCSIFFLAGS:
   1357          1.1     joerg 		if (ifp->if_flags & IFF_UP) {
   1358          1.1     joerg 			if (ifp->if_flags & IFF_RUNNING)
   1359          1.1     joerg 				rum_update_promisc(sc);
   1360          1.1     joerg 			else
   1361          1.1     joerg 				rum_init(ifp);
   1362          1.1     joerg 		} else {
   1363          1.1     joerg 			if (ifp->if_flags & IFF_RUNNING)
   1364          1.1     joerg 				rum_stop(ifp, 1);
   1365          1.1     joerg 		}
   1366          1.1     joerg 		break;
   1367          1.1     joerg 
   1368          1.1     joerg 	default:
   1369          1.1     joerg 		error = ieee80211_ioctl(ic, cmd, data);
   1370          1.1     joerg 	}
   1371          1.1     joerg 
   1372          1.1     joerg 	if (error == ENETRESET) {
   1373          1.1     joerg 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   1374          1.1     joerg 		    (IFF_UP | IFF_RUNNING))
   1375          1.1     joerg 			rum_init(ifp);
   1376          1.1     joerg 		error = 0;
   1377          1.1     joerg 	}
   1378          1.1     joerg 
   1379          1.1     joerg 	splx(s);
   1380          1.1     joerg 
   1381          1.1     joerg 	return error;
   1382          1.1     joerg }
   1383          1.1     joerg 
   1384          1.1     joerg Static void
   1385          1.1     joerg rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
   1386          1.1     joerg {
   1387          1.1     joerg 	usb_device_request_t req;
   1388          1.1     joerg 	usbd_status error;
   1389          1.1     joerg 
   1390          1.1     joerg 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
   1391          1.1     joerg 	req.bRequest = RT2573_READ_EEPROM;
   1392          1.1     joerg 	USETW(req.wValue, 0);
   1393          1.1     joerg 	USETW(req.wIndex, addr);
   1394          1.1     joerg 	USETW(req.wLength, len);
   1395          1.1     joerg 
   1396          1.1     joerg 	error = usbd_do_request(sc->sc_udev, &req, buf);
   1397          1.1     joerg 	if (error != 0) {
   1398          1.1     joerg 		printf("%s: could not read EEPROM: %s\n",
   1399          1.1     joerg 		    USBDEVNAME(sc->sc_dev), usbd_errstr(error));
   1400          1.1     joerg 	}
   1401          1.1     joerg }
   1402          1.1     joerg 
   1403          1.1     joerg Static uint32_t
   1404          1.1     joerg rum_read(struct rum_softc *sc, uint16_t reg)
   1405          1.1     joerg {
   1406          1.1     joerg 	uint32_t val;
   1407          1.1     joerg 
   1408          1.1     joerg 	rum_read_multi(sc, reg, &val, sizeof val);
   1409          1.1     joerg 
   1410          1.1     joerg 	return le32toh(val);
   1411          1.1     joerg }
   1412          1.1     joerg 
   1413          1.1     joerg Static void
   1414          1.1     joerg rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
   1415          1.1     joerg {
   1416          1.1     joerg 	usb_device_request_t req;
   1417          1.1     joerg 	usbd_status error;
   1418          1.1     joerg 
   1419          1.1     joerg 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
   1420          1.1     joerg 	req.bRequest = RT2573_READ_MULTI_MAC;
   1421          1.1     joerg 	USETW(req.wValue, 0);
   1422          1.1     joerg 	USETW(req.wIndex, reg);
   1423          1.1     joerg 	USETW(req.wLength, len);
   1424          1.1     joerg 
   1425          1.1     joerg 	error = usbd_do_request(sc->sc_udev, &req, buf);
   1426          1.1     joerg 	if (error != 0) {
   1427          1.1     joerg 		printf("%s: could not multi read MAC register: %s\n",
   1428          1.1     joerg 		    USBDEVNAME(sc->sc_dev), usbd_errstr(error));
   1429          1.1     joerg 	}
   1430          1.1     joerg }
   1431          1.1     joerg 
   1432          1.1     joerg Static void
   1433          1.1     joerg rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
   1434          1.1     joerg {
   1435          1.1     joerg 	uint32_t tmp = htole32(val);
   1436          1.1     joerg 
   1437          1.1     joerg 	rum_write_multi(sc, reg, &tmp, sizeof tmp);
   1438          1.1     joerg }
   1439          1.1     joerg 
   1440          1.1     joerg Static void
   1441          1.1     joerg rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
   1442          1.1     joerg {
   1443          1.1     joerg 	usb_device_request_t req;
   1444          1.1     joerg 	usbd_status error;
   1445          1.1     joerg 
   1446          1.1     joerg 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
   1447          1.1     joerg 	req.bRequest = RT2573_WRITE_MULTI_MAC;
   1448          1.1     joerg 	USETW(req.wValue, 0);
   1449          1.1     joerg 	USETW(req.wIndex, reg);
   1450          1.1     joerg 	USETW(req.wLength, len);
   1451          1.1     joerg 
   1452          1.1     joerg 	error = usbd_do_request(sc->sc_udev, &req, buf);
   1453          1.1     joerg 	if (error != 0) {
   1454          1.1     joerg 		printf("%s: could not multi write MAC register: %s\n",
   1455          1.1     joerg 		    USBDEVNAME(sc->sc_dev), usbd_errstr(error));
   1456          1.1     joerg 	}
   1457          1.1     joerg }
   1458          1.1     joerg 
   1459          1.1     joerg Static void
   1460          1.1     joerg rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
   1461          1.1     joerg {
   1462          1.1     joerg 	uint32_t tmp;
   1463          1.1     joerg 	int ntries;
   1464          1.1     joerg 
   1465          1.1     joerg 	for (ntries = 0; ntries < 5; ntries++) {
   1466          1.1     joerg 		if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
   1467          1.1     joerg 			break;
   1468          1.1     joerg 	}
   1469          1.1     joerg 	if (ntries == 5) {
   1470          1.1     joerg 		printf("%s: could not write to BBP\n", USBDEVNAME(sc->sc_dev));
   1471          1.1     joerg 		return;
   1472          1.1     joerg 	}
   1473          1.1     joerg 
   1474          1.1     joerg 	tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
   1475          1.1     joerg 	rum_write(sc, RT2573_PHY_CSR3, tmp);
   1476          1.1     joerg }
   1477          1.1     joerg 
   1478          1.1     joerg Static uint8_t
   1479          1.1     joerg rum_bbp_read(struct rum_softc *sc, uint8_t reg)
   1480          1.1     joerg {
   1481          1.1     joerg 	uint32_t val;
   1482          1.1     joerg 	int ntries;
   1483          1.1     joerg 
   1484          1.1     joerg 	for (ntries = 0; ntries < 5; ntries++) {
   1485          1.1     joerg 		if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
   1486          1.1     joerg 			break;
   1487          1.1     joerg 	}
   1488          1.1     joerg 	if (ntries == 5) {
   1489          1.1     joerg 		printf("%s: could not read BBP\n", USBDEVNAME(sc->sc_dev));
   1490          1.1     joerg 		return 0;
   1491          1.1     joerg 	}
   1492          1.1     joerg 
   1493          1.1     joerg 	val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
   1494          1.1     joerg 	rum_write(sc, RT2573_PHY_CSR3, val);
   1495          1.1     joerg 
   1496          1.1     joerg 	for (ntries = 0; ntries < 100; ntries++) {
   1497          1.1     joerg 		val = rum_read(sc, RT2573_PHY_CSR3);
   1498          1.1     joerg 		if (!(val & RT2573_BBP_BUSY))
   1499          1.1     joerg 			return val & 0xff;
   1500          1.1     joerg 		DELAY(1);
   1501          1.1     joerg 	}
   1502          1.1     joerg 
   1503          1.1     joerg 	printf("%s: could not read BBP\n", USBDEVNAME(sc->sc_dev));
   1504          1.1     joerg 	return 0;
   1505          1.1     joerg }
   1506          1.1     joerg 
   1507          1.1     joerg Static void
   1508          1.1     joerg rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
   1509          1.1     joerg {
   1510          1.1     joerg 	uint32_t tmp;
   1511          1.1     joerg 	int ntries;
   1512          1.1     joerg 
   1513          1.1     joerg 	for (ntries = 0; ntries < 5; ntries++) {
   1514          1.1     joerg 		if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
   1515          1.1     joerg 			break;
   1516          1.1     joerg 	}
   1517          1.1     joerg 	if (ntries == 5) {
   1518          1.1     joerg 		printf("%s: could not write to RF\n", USBDEVNAME(sc->sc_dev));
   1519          1.1     joerg 		return;
   1520          1.1     joerg 	}
   1521          1.1     joerg 
   1522          1.1     joerg 	tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
   1523          1.1     joerg 	    (reg & 3);
   1524          1.1     joerg 	rum_write(sc, RT2573_PHY_CSR4, tmp);
   1525          1.1     joerg 
   1526          1.1     joerg 	/* remember last written value in sc */
   1527          1.1     joerg 	sc->rf_regs[reg] = val;
   1528          1.1     joerg 
   1529          1.1     joerg 	DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff));
   1530          1.1     joerg }
   1531          1.1     joerg 
   1532          1.1     joerg Static void
   1533          1.1     joerg rum_select_antenna(struct rum_softc *sc)
   1534          1.1     joerg {
   1535          1.1     joerg 	uint8_t bbp4, bbp77;
   1536          1.1     joerg 	uint32_t tmp;
   1537          1.1     joerg 
   1538          1.1     joerg 	bbp4  = rum_bbp_read(sc, 4);
   1539          1.1     joerg 	bbp77 = rum_bbp_read(sc, 77);
   1540          1.1     joerg 
   1541          1.1     joerg 	/* TBD */
   1542          1.1     joerg 
   1543          1.1     joerg 	/* make sure Rx is disabled before switching antenna */
   1544          1.1     joerg 	tmp = rum_read(sc, RT2573_TXRX_CSR0);
   1545          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
   1546          1.1     joerg 
   1547          1.1     joerg 	rum_bbp_write(sc,  4, bbp4);
   1548          1.1     joerg 	rum_bbp_write(sc, 77, bbp77);
   1549          1.1     joerg 
   1550          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR0, tmp);
   1551          1.1     joerg }
   1552          1.1     joerg 
   1553          1.1     joerg /*
   1554          1.1     joerg  * Enable multi-rate retries for frames sent at OFDM rates.
   1555          1.1     joerg  * In 802.11b/g mode, allow fallback to CCK rates.
   1556          1.1     joerg  */
   1557          1.1     joerg Static void
   1558          1.1     joerg rum_enable_mrr(struct rum_softc *sc)
   1559          1.1     joerg {
   1560          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1561          1.1     joerg 	uint32_t tmp;
   1562          1.1     joerg 
   1563          1.1     joerg 	tmp = rum_read(sc, RT2573_TXRX_CSR4);
   1564          1.1     joerg 
   1565          1.1     joerg 	tmp &= ~RT2573_MRR_CCK_FALLBACK;
   1566          1.1     joerg 	if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
   1567          1.1     joerg 		tmp |= RT2573_MRR_CCK_FALLBACK;
   1568          1.1     joerg 	tmp |= RT2573_MRR_ENABLED;
   1569          1.1     joerg 
   1570          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR4, tmp);
   1571          1.1     joerg }
   1572          1.1     joerg 
   1573          1.1     joerg Static void
   1574          1.1     joerg rum_set_txpreamble(struct rum_softc *sc)
   1575          1.1     joerg {
   1576          1.1     joerg 	uint32_t tmp;
   1577          1.1     joerg 
   1578          1.1     joerg 	tmp = rum_read(sc, RT2573_TXRX_CSR4);
   1579          1.1     joerg 
   1580          1.1     joerg 	tmp &= ~RT2573_SHORT_PREAMBLE;
   1581          1.1     joerg 	if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
   1582          1.1     joerg 		tmp |= RT2573_SHORT_PREAMBLE;
   1583          1.1     joerg 
   1584          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR4, tmp);
   1585          1.1     joerg }
   1586          1.1     joerg 
   1587          1.1     joerg Static void
   1588          1.1     joerg rum_set_basicrates(struct rum_softc *sc)
   1589          1.1     joerg {
   1590          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1591          1.1     joerg 
   1592          1.1     joerg 	/* update basic rate set */
   1593          1.1     joerg 	if (ic->ic_curmode == IEEE80211_MODE_11B) {
   1594          1.1     joerg 		/* 11b basic rates: 1, 2Mbps */
   1595          1.1     joerg 		rum_write(sc, RT2573_TXRX_CSR5, 0x3);
   1596          1.1     joerg 	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) {
   1597          1.1     joerg 		/* 11a basic rates: 6, 12, 24Mbps */
   1598          1.1     joerg 		rum_write(sc, RT2573_TXRX_CSR5, 0x150);
   1599          1.1     joerg 	} else {
   1600          1.1     joerg 		/* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
   1601          1.1     joerg 		rum_write(sc, RT2573_TXRX_CSR5, 0x15f);
   1602          1.1     joerg 	}
   1603          1.1     joerg }
   1604          1.1     joerg 
   1605          1.1     joerg /*
   1606          1.1     joerg  * Reprogram MAC/BBP to switch to a new band.  Values taken from the reference
   1607          1.1     joerg  * driver.
   1608          1.1     joerg  */
   1609          1.1     joerg Static void
   1610          1.1     joerg rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
   1611          1.1     joerg {
   1612          1.1     joerg 	uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
   1613          1.1     joerg 	uint32_t tmp;
   1614          1.1     joerg 
   1615          1.1     joerg 	/* update all BBP registers that depend on the band */
   1616          1.1     joerg 	bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
   1617          1.1     joerg 	bbp35 = 0x50; bbp97 = 0x48; bbp98  = 0x48;
   1618          1.1     joerg 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
   1619          1.1     joerg 		bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
   1620          1.1     joerg 		bbp35 += 0x10; bbp97 += 0x10; bbp98  += 0x10;
   1621          1.1     joerg 	}
   1622          1.1     joerg 	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
   1623          1.1     joerg 	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
   1624          1.1     joerg 		bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
   1625          1.1     joerg 	}
   1626          1.1     joerg 
   1627          1.1     joerg 	sc->bbp17 = bbp17;
   1628          1.1     joerg 	rum_bbp_write(sc,  17, bbp17);
   1629          1.1     joerg 	rum_bbp_write(sc,  96, bbp96);
   1630          1.1     joerg 	rum_bbp_write(sc, 104, bbp104);
   1631          1.1     joerg 
   1632          1.1     joerg 	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
   1633          1.1     joerg 	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
   1634          1.1     joerg 		rum_bbp_write(sc, 75, 0x80);
   1635          1.1     joerg 		rum_bbp_write(sc, 86, 0x80);
   1636          1.1     joerg 		rum_bbp_write(sc, 88, 0x80);
   1637          1.1     joerg 	}
   1638          1.1     joerg 
   1639          1.1     joerg 	rum_bbp_write(sc, 35, bbp35);
   1640          1.1     joerg 	rum_bbp_write(sc, 97, bbp97);
   1641          1.1     joerg 	rum_bbp_write(sc, 98, bbp98);
   1642          1.1     joerg 
   1643          1.1     joerg 	tmp = rum_read(sc, RT2573_PHY_CSR0);
   1644          1.1     joerg 	tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
   1645          1.1     joerg 	if (IEEE80211_IS_CHAN_2GHZ(c))
   1646          1.1     joerg 		tmp |= RT2573_PA_PE_2GHZ;
   1647          1.1     joerg 	else
   1648          1.1     joerg 		tmp |= RT2573_PA_PE_5GHZ;
   1649          1.1     joerg 	rum_write(sc, RT2573_PHY_CSR0, tmp);
   1650          1.1     joerg 
   1651          1.1     joerg 	/* 802.11a uses a 16 microseconds short interframe space */
   1652          1.1     joerg 	sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10;
   1653          1.1     joerg }
   1654          1.1     joerg 
   1655          1.1     joerg Static void
   1656          1.1     joerg rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
   1657          1.1     joerg {
   1658          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1659          1.1     joerg 	const struct rfprog *rfprog;
   1660          1.1     joerg 	uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
   1661          1.1     joerg 	int8_t power;
   1662          1.1     joerg 	u_int i, chan;
   1663          1.1     joerg 
   1664          1.1     joerg 	chan = ieee80211_chan2ieee(ic, c);
   1665          1.1     joerg 	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
   1666          1.1     joerg 		return;
   1667          1.1     joerg 
   1668          1.1     joerg 	/* select the appropriate RF settings based on what EEPROM says */
   1669          1.1     joerg 	rfprog = (sc->rf_rev == RT2573_RF_5225 ||
   1670          1.1     joerg 		  sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
   1671          1.1     joerg 
   1672          1.1     joerg 	/* find the settings for this channel (we know it exists) */
   1673          1.1     joerg 	for (i = 0; rfprog[i].chan != chan; i++);
   1674          1.1     joerg 
   1675          1.1     joerg 	power = sc->txpow[i];
   1676          1.1     joerg 	if (power < 0) {
   1677          1.1     joerg 		bbp94 += power;
   1678          1.1     joerg 		power = 0;
   1679          1.1     joerg 	} else if (power > 31) {
   1680          1.1     joerg 		bbp94 += power - 31;
   1681          1.1     joerg 		power = 31;
   1682          1.1     joerg 	}
   1683          1.1     joerg 
   1684          1.1     joerg 	/*
   1685          1.1     joerg 	 * If we are switching from the 2GHz band to the 5GHz band or
   1686          1.1     joerg 	 * vice-versa, BBP registers need to be reprogrammed.
   1687          1.1     joerg 	 */
   1688          1.1     joerg 	if (c->ic_flags != ic->ic_curchan->ic_flags) {
   1689          1.1     joerg 		rum_select_band(sc, c);
   1690          1.1     joerg 		rum_select_antenna(sc);
   1691          1.1     joerg 	}
   1692          1.1     joerg 	ic->ic_curchan = c;
   1693          1.1     joerg 
   1694          1.1     joerg 	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
   1695          1.1     joerg 	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
   1696          1.1     joerg 	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
   1697          1.1     joerg 	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
   1698          1.1     joerg 
   1699          1.1     joerg 	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
   1700          1.1     joerg 	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
   1701          1.1     joerg 	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
   1702          1.1     joerg 	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
   1703          1.1     joerg 
   1704          1.1     joerg 	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
   1705          1.1     joerg 	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
   1706          1.1     joerg 	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
   1707          1.1     joerg 	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
   1708          1.1     joerg 
   1709          1.1     joerg 	DELAY(10);
   1710          1.1     joerg 
   1711          1.1     joerg 	/* enable smart mode for MIMO-capable RFs */
   1712          1.1     joerg 	bbp3 = rum_bbp_read(sc, 3);
   1713          1.1     joerg 
   1714          1.1     joerg 	bbp3 &= ~RT2573_SMART_MODE;
   1715          1.1     joerg 	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
   1716          1.1     joerg 		bbp3 |= RT2573_SMART_MODE;
   1717          1.1     joerg 
   1718          1.1     joerg 	rum_bbp_write(sc, 3, bbp3);
   1719          1.1     joerg 
   1720          1.1     joerg 	if (bbp94 != RT2573_BBPR94_DEFAULT)
   1721          1.1     joerg 		rum_bbp_write(sc, 94, bbp94);
   1722          1.1     joerg }
   1723          1.1     joerg 
   1724          1.1     joerg /*
   1725          1.1     joerg  * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
   1726          1.1     joerg  * and HostAP operating modes.
   1727          1.1     joerg  */
   1728          1.1     joerg Static void
   1729          1.1     joerg rum_enable_tsf_sync(struct rum_softc *sc)
   1730          1.1     joerg {
   1731          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1732          1.1     joerg 	uint32_t tmp;
   1733          1.1     joerg 
   1734          1.1     joerg 	if (ic->ic_opmode != IEEE80211_M_STA) {
   1735          1.1     joerg 		/*
   1736          1.1     joerg 		 * Change default 16ms TBTT adjustment to 8ms.
   1737          1.1     joerg 		 * Must be done before enabling beacon generation.
   1738          1.1     joerg 		 */
   1739          1.1     joerg 		rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
   1740          1.1     joerg 	}
   1741          1.1     joerg 
   1742          1.1     joerg 	tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
   1743          1.1     joerg 
   1744          1.1     joerg 	/* set beacon interval (in 1/16ms unit) */
   1745          1.1     joerg 	tmp |= ic->ic_bss->ni_intval * 16;
   1746          1.1     joerg 
   1747          1.1     joerg 	tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
   1748          1.1     joerg 	if (ic->ic_opmode == IEEE80211_M_STA)
   1749          1.1     joerg 		tmp |= RT2573_TSF_MODE(1);
   1750          1.1     joerg 	else
   1751          1.1     joerg 		tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
   1752          1.1     joerg 
   1753          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR9, tmp);
   1754          1.1     joerg }
   1755          1.1     joerg 
   1756          1.1     joerg Static void
   1757          1.1     joerg rum_update_slot(struct rum_softc *sc)
   1758          1.1     joerg {
   1759          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1760          1.1     joerg 	uint8_t slottime;
   1761          1.1     joerg 	uint32_t tmp;
   1762          1.1     joerg 
   1763          1.1     joerg 	slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
   1764          1.1     joerg 
   1765          1.1     joerg 	tmp = rum_read(sc, RT2573_MAC_CSR9);
   1766          1.1     joerg 	tmp = (tmp & ~0xff) | slottime;
   1767          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR9, tmp);
   1768          1.1     joerg 
   1769          1.1     joerg 	DPRINTF(("setting slot time to %uus\n", slottime));
   1770          1.1     joerg }
   1771          1.1     joerg 
   1772          1.1     joerg Static void
   1773          1.1     joerg rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
   1774          1.1     joerg {
   1775          1.1     joerg 	uint32_t tmp;
   1776          1.1     joerg 
   1777          1.1     joerg 	tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
   1778          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR4, tmp);
   1779          1.1     joerg 
   1780          1.1     joerg 	tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
   1781          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR5, tmp);
   1782          1.1     joerg }
   1783          1.1     joerg 
   1784          1.1     joerg Static void
   1785          1.1     joerg rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
   1786          1.1     joerg {
   1787          1.1     joerg 	uint32_t tmp;
   1788          1.1     joerg 
   1789          1.1     joerg 	tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
   1790          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR2, tmp);
   1791          1.1     joerg 
   1792          1.1     joerg 	tmp = addr[4] | addr[5] << 8 | 0xff << 16;
   1793          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR3, tmp);
   1794          1.1     joerg }
   1795          1.1     joerg 
   1796          1.1     joerg Static void
   1797          1.1     joerg rum_update_promisc(struct rum_softc *sc)
   1798          1.1     joerg {
   1799          1.1     joerg 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
   1800          1.1     joerg 	uint32_t tmp;
   1801          1.1     joerg 
   1802          1.1     joerg 	tmp = rum_read(sc, RT2573_TXRX_CSR0);
   1803          1.1     joerg 
   1804          1.1     joerg 	tmp &= ~RT2573_DROP_NOT_TO_ME;
   1805          1.1     joerg 	if (!(ifp->if_flags & IFF_PROMISC))
   1806          1.1     joerg 		tmp |= RT2573_DROP_NOT_TO_ME;
   1807          1.1     joerg 
   1808          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR0, tmp);
   1809          1.1     joerg 
   1810          1.1     joerg 	DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
   1811          1.1     joerg 	    "entering" : "leaving"));
   1812          1.1     joerg }
   1813          1.1     joerg 
   1814          1.1     joerg Static const char *
   1815          1.1     joerg rum_get_rf(int rev)
   1816          1.1     joerg {
   1817          1.1     joerg 	switch (rev) {
   1818          1.1     joerg 	case RT2573_RF_2527:	return "RT2527 (MIMO XR)";
   1819          1.1     joerg 	case RT2573_RF_2528:	return "RT2528";
   1820          1.1     joerg 	case RT2573_RF_5225:	return "RT5225 (MIMO XR)";
   1821          1.1     joerg 	case RT2573_RF_5226:	return "RT5226";
   1822          1.1     joerg 	default:		return "unknown";
   1823          1.1     joerg 	}
   1824          1.1     joerg }
   1825          1.1     joerg 
   1826          1.1     joerg Static void
   1827          1.1     joerg rum_read_eeprom(struct rum_softc *sc)
   1828          1.1     joerg {
   1829          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1830          1.1     joerg 	uint16_t val;
   1831          1.1     joerg #ifdef RUM_DEBUG
   1832          1.1     joerg 	int i;
   1833          1.1     joerg #endif
   1834          1.1     joerg 
   1835          1.1     joerg 	/* read MAC/BBP type */
   1836          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_MACBBP, &val, 2);
   1837          1.1     joerg 	sc->macbbp_rev = le16toh(val);
   1838          1.1     joerg 
   1839          1.1     joerg 	/* read MAC address */
   1840          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_myaddr, 6);
   1841          1.1     joerg 
   1842          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
   1843          1.1     joerg 	val = le16toh(val);
   1844          1.1     joerg 	sc->rf_rev =   (val >> 11) & 0x1f;
   1845          1.1     joerg 	sc->hw_radio = (val >> 10) & 0x1;
   1846          1.1     joerg 	sc->rx_ant =   (val >> 4)  & 0x3;
   1847          1.1     joerg 	sc->tx_ant =   (val >> 2)  & 0x3;
   1848          1.1     joerg 	sc->nb_ant =   val & 0x3;
   1849          1.1     joerg 
   1850          1.1     joerg 	DPRINTF(("RF revision=%d\n", sc->rf_rev));
   1851          1.1     joerg 
   1852          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
   1853          1.1     joerg 	val = le16toh(val);
   1854          1.1     joerg 	sc->ext_5ghz_lna = (val >> 6) & 0x1;
   1855          1.1     joerg 	sc->ext_2ghz_lna = (val >> 4) & 0x1;
   1856          1.1     joerg 
   1857          1.1     joerg 	DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
   1858          1.1     joerg 	    sc->ext_2ghz_lna, sc->ext_5ghz_lna));
   1859          1.1     joerg 
   1860          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
   1861          1.1     joerg 	val = le16toh(val);
   1862          1.1     joerg 	if ((val & 0xff) != 0xff)
   1863          1.1     joerg 		sc->rssi_2ghz_corr = (int8_t)(val & 0xff);	/* signed */
   1864          1.1     joerg 
   1865          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
   1866          1.1     joerg 	val = le16toh(val);
   1867          1.1     joerg 	if ((val & 0xff) != 0xff)
   1868          1.1     joerg 		sc->rssi_5ghz_corr = (int8_t)(val & 0xff);	/* signed */
   1869          1.1     joerg 
   1870          1.1     joerg 	DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
   1871          1.1     joerg 	    sc->rssi_2ghz_corr, sc->rssi_5ghz_corr));
   1872          1.1     joerg 
   1873          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
   1874          1.1     joerg 	val = le16toh(val);
   1875          1.1     joerg 	if ((val & 0xff) != 0xff)
   1876          1.1     joerg 		sc->rffreq = val & 0xff;
   1877          1.1     joerg 
   1878          1.1     joerg 	DPRINTF(("RF freq=%d\n", sc->rffreq));
   1879          1.1     joerg 
   1880          1.1     joerg 	/* read Tx power for all a/b/g channels */
   1881          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
   1882          1.1     joerg 	/* XXX default Tx power for 802.11a channels */
   1883          1.1     joerg 	memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
   1884          1.1     joerg #ifdef RUM_DEBUG
   1885          1.1     joerg 	for (i = 0; i < 14; i++)
   1886          1.1     joerg 		DPRINTF(("Channel=%d Tx power=%d\n", i + 1,  sc->txpow[i]));
   1887          1.1     joerg #endif
   1888          1.1     joerg 
   1889          1.1     joerg 	/* read default values for BBP registers */
   1890          1.1     joerg 	rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
   1891          1.1     joerg #ifdef RUM_DEBUG
   1892          1.1     joerg 	for (i = 0; i < 14; i++) {
   1893          1.1     joerg 		if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
   1894          1.1     joerg 			continue;
   1895          1.1     joerg 		DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
   1896          1.1     joerg 		    sc->bbp_prom[i].val));
   1897          1.1     joerg 	}
   1898          1.1     joerg #endif
   1899          1.1     joerg }
   1900          1.1     joerg 
   1901          1.1     joerg Static int
   1902          1.1     joerg rum_bbp_init(struct rum_softc *sc)
   1903          1.1     joerg {
   1904          1.1     joerg #define N(a)	(sizeof (a) / sizeof ((a)[0]))
   1905          1.1     joerg 	int i, ntries;
   1906          1.1     joerg 	uint8_t val;
   1907          1.1     joerg 
   1908          1.1     joerg 	/* wait for BBP to be ready */
   1909          1.1     joerg 	for (ntries = 0; ntries < 100; ntries++) {
   1910          1.1     joerg 		val = rum_bbp_read(sc, 0);
   1911          1.1     joerg 		if (val != 0 && val != 0xff)
   1912          1.1     joerg 			break;
   1913          1.1     joerg 		DELAY(1000);
   1914          1.1     joerg 	}
   1915          1.1     joerg 	if (ntries == 100) {
   1916          1.1     joerg 		printf("%s: timeout waiting for BBP\n",
   1917          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
   1918          1.1     joerg 		return EIO;
   1919          1.1     joerg 	}
   1920          1.1     joerg 
   1921          1.1     joerg 	/* initialize BBP registers to default values */
   1922          1.1     joerg 	for (i = 0; i < N(rum_def_bbp); i++)
   1923          1.1     joerg 		rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
   1924          1.1     joerg 
   1925          1.1     joerg 	/* write vendor-specific BBP values (from EEPROM) */
   1926          1.1     joerg 	for (i = 0; i < 16; i++) {
   1927          1.1     joerg 		if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
   1928          1.1     joerg 			continue;
   1929          1.1     joerg 		rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
   1930          1.1     joerg 	}
   1931          1.1     joerg 
   1932          1.1     joerg 	return 0;
   1933          1.1     joerg #undef N
   1934          1.1     joerg }
   1935          1.1     joerg 
   1936          1.1     joerg Static int
   1937          1.1     joerg rum_init(struct ifnet *ifp)
   1938          1.1     joerg {
   1939          1.1     joerg #define N(a)	(sizeof (a) / sizeof ((a)[0]))
   1940          1.1     joerg 	struct rum_softc *sc = ifp->if_softc;
   1941          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   1942          1.1     joerg 	struct rum_rx_data *data;
   1943          1.1     joerg 	uint32_t tmp;
   1944          1.1     joerg 	usbd_status error = 0;
   1945          1.1     joerg 	int i, ntries;
   1946          1.1     joerg 
   1947          1.1     joerg 	if ((sc->sc_flags & RT2573_FWLOADED) == 0) {
   1948          1.1     joerg 		if (rum_attachhook(sc))
   1949          1.1     joerg 			goto fail;
   1950          1.1     joerg 	}
   1951          1.1     joerg 
   1952          1.1     joerg 	rum_stop(ifp, 0);
   1953          1.1     joerg 
   1954          1.1     joerg 	/* initialize MAC registers to default values */
   1955          1.1     joerg 	for (i = 0; i < N(rum_def_mac); i++)
   1956          1.1     joerg 		rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
   1957          1.1     joerg 
   1958          1.1     joerg 	/* set host ready */
   1959          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR1, 3);
   1960          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR1, 0);
   1961          1.1     joerg 
   1962          1.1     joerg 	/* wait for BBP/RF to wakeup */
   1963          1.1     joerg 	for (ntries = 0; ntries < 1000; ntries++) {
   1964          1.1     joerg 		if (rum_read(sc, RT2573_MAC_CSR12) & 8)
   1965          1.1     joerg 			break;
   1966          1.1     joerg 		rum_write(sc, RT2573_MAC_CSR12, 4);	/* force wakeup */
   1967          1.1     joerg 		DELAY(1000);
   1968          1.1     joerg 	}
   1969          1.1     joerg 	if (ntries == 1000) {
   1970          1.1     joerg 		printf("%s: timeout waiting for BBP/RF to wakeup\n",
   1971          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
   1972          1.1     joerg 		goto fail;
   1973          1.1     joerg 	}
   1974          1.1     joerg 
   1975          1.1     joerg 	if ((error = rum_bbp_init(sc)) != 0)
   1976          1.1     joerg 		goto fail;
   1977          1.1     joerg 
   1978          1.1     joerg 	/* select default channel */
   1979          1.1     joerg 	rum_select_band(sc, ic->ic_curchan);
   1980          1.1     joerg 	rum_select_antenna(sc);
   1981          1.1     joerg 	rum_set_chan(sc, ic->ic_curchan);
   1982          1.1     joerg 
   1983          1.1     joerg 	/* clear STA registers */
   1984          1.1     joerg 	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
   1985          1.1     joerg 
   1986          1.1     joerg 	IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
   1987          1.1     joerg 	rum_set_macaddr(sc, ic->ic_myaddr);
   1988          1.1     joerg 
   1989          1.1     joerg 	/* initialize ASIC */
   1990          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR1, 4);
   1991          1.1     joerg 
   1992          1.1     joerg 	/*
   1993          1.1     joerg 	 * Allocate xfer for AMRR statistics requests.
   1994          1.1     joerg 	 */
   1995          1.1     joerg 	sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev);
   1996          1.1     joerg 	if (sc->amrr_xfer == NULL) {
   1997          1.1     joerg 		printf("%s: could not allocate AMRR xfer\n",
   1998          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
   1999          1.1     joerg 		goto fail;
   2000          1.1     joerg 	}
   2001          1.1     joerg 
   2002          1.1     joerg 	/*
   2003          1.1     joerg 	 * Open Tx and Rx USB bulk pipes.
   2004          1.1     joerg 	 */
   2005          1.1     joerg 	error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
   2006          1.1     joerg 	    &sc->sc_tx_pipeh);
   2007          1.1     joerg 	if (error != 0) {
   2008          1.1     joerg 		printf("%s: could not open Tx pipe: %s\n",
   2009          1.1     joerg 		    USBDEVNAME(sc->sc_dev), usbd_errstr(error));
   2010          1.1     joerg 		goto fail;
   2011          1.1     joerg 	}
   2012          1.1     joerg 
   2013          1.1     joerg 	error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
   2014          1.1     joerg 	    &sc->sc_rx_pipeh);
   2015          1.1     joerg 	if (error != 0) {
   2016          1.1     joerg 		printf("%s: could not open Rx pipe: %s\n",
   2017          1.1     joerg 		    USBDEVNAME(sc->sc_dev), usbd_errstr(error));
   2018          1.1     joerg 		goto fail;
   2019          1.1     joerg 	}
   2020          1.1     joerg 
   2021          1.1     joerg 	/*
   2022          1.1     joerg 	 * Allocate Tx and Rx xfer queues.
   2023          1.1     joerg 	 */
   2024          1.1     joerg 	error = rum_alloc_tx_list(sc);
   2025          1.1     joerg 	if (error != 0) {
   2026          1.1     joerg 		printf("%s: could not allocate Tx list\n",
   2027          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
   2028          1.1     joerg 		goto fail;
   2029          1.1     joerg 	}
   2030          1.1     joerg 
   2031          1.1     joerg 	error = rum_alloc_rx_list(sc);
   2032          1.1     joerg 	if (error != 0) {
   2033          1.1     joerg 		printf("%s: could not allocate Rx list\n",
   2034          1.1     joerg 		    USBDEVNAME(sc->sc_dev));
   2035          1.1     joerg 		goto fail;
   2036          1.1     joerg 	}
   2037          1.1     joerg 
   2038          1.1     joerg 	/*
   2039          1.1     joerg 	 * Start up the receive pipe.
   2040          1.1     joerg 	 */
   2041          1.1     joerg 	for (i = 0; i < RT2573_RX_LIST_COUNT; i++) {
   2042          1.1     joerg 		data = &sc->rx_data[i];
   2043          1.1     joerg 
   2044          1.1     joerg 		usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf,
   2045          1.1     joerg 		    MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof);
   2046          1.1     joerg 		usbd_transfer(data->xfer);
   2047          1.1     joerg 	}
   2048          1.1     joerg 
   2049          1.1     joerg 	/* update Rx filter */
   2050          1.1     joerg 	tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
   2051          1.1     joerg 
   2052          1.1     joerg 	tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
   2053          1.1     joerg 	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
   2054          1.1     joerg 		tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
   2055          1.1     joerg 		       RT2573_DROP_ACKCTS;
   2056          1.1     joerg 		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
   2057          1.1     joerg 			tmp |= RT2573_DROP_TODS;
   2058          1.1     joerg 		if (!(ifp->if_flags & IFF_PROMISC))
   2059          1.1     joerg 			tmp |= RT2573_DROP_NOT_TO_ME;
   2060          1.1     joerg 	}
   2061          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR0, tmp);
   2062          1.1     joerg 
   2063          1.1     joerg 	ifp->if_flags &= ~IFF_OACTIVE;
   2064          1.1     joerg 	ifp->if_flags |= IFF_RUNNING;
   2065          1.1     joerg 
   2066          1.1     joerg 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   2067          1.1     joerg 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   2068          1.1     joerg 	else
   2069          1.1     joerg 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   2070          1.1     joerg 
   2071          1.1     joerg 	return 0;
   2072          1.1     joerg 
   2073          1.1     joerg fail:	rum_stop(ifp, 1);
   2074          1.1     joerg 	return error;
   2075          1.1     joerg #undef N
   2076          1.1     joerg }
   2077          1.1     joerg 
   2078          1.1     joerg Static void
   2079          1.1     joerg rum_stop(struct ifnet *ifp, int disable)
   2080          1.1     joerg {
   2081          1.1     joerg 	struct rum_softc *sc = ifp->if_softc;
   2082          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   2083          1.1     joerg 	uint32_t tmp;
   2084          1.1     joerg 
   2085          1.1     joerg 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);	/* free all nodes */
   2086          1.1     joerg 
   2087          1.1     joerg 	sc->sc_tx_timer = 0;
   2088          1.1     joerg 	ifp->if_timer = 0;
   2089          1.1     joerg 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   2090          1.1     joerg 
   2091          1.1     joerg 	/* disable Rx */
   2092          1.1     joerg 	tmp = rum_read(sc, RT2573_TXRX_CSR0);
   2093          1.1     joerg 	rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
   2094          1.1     joerg 
   2095          1.1     joerg 	/* reset ASIC */
   2096          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR1, 3);
   2097          1.1     joerg 	rum_write(sc, RT2573_MAC_CSR1, 0);
   2098          1.1     joerg 
   2099          1.1     joerg 	if (sc->sc_rx_pipeh != NULL) {
   2100          1.1     joerg 		usbd_abort_pipe(sc->sc_rx_pipeh);
   2101          1.1     joerg 		usbd_close_pipe(sc->sc_rx_pipeh);
   2102          1.1     joerg 		sc->sc_rx_pipeh = NULL;
   2103          1.1     joerg 	}
   2104          1.1     joerg 
   2105          1.1     joerg 	if (sc->sc_tx_pipeh != NULL) {
   2106          1.1     joerg 		usbd_abort_pipe(sc->sc_tx_pipeh);
   2107          1.1     joerg 		usbd_close_pipe(sc->sc_tx_pipeh);
   2108          1.1     joerg 		sc->sc_tx_pipeh = NULL;
   2109          1.1     joerg 	}
   2110          1.1     joerg 
   2111          1.1     joerg 	rum_free_rx_list(sc);
   2112          1.1     joerg 	rum_free_tx_list(sc);
   2113          1.1     joerg }
   2114          1.1     joerg 
   2115          1.1     joerg Static int
   2116          1.1     joerg rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
   2117          1.1     joerg {
   2118          1.1     joerg 	usb_device_request_t req;
   2119          1.1     joerg 	uint16_t reg = RT2573_MCU_CODE_BASE;
   2120          1.1     joerg 	usbd_status error;
   2121          1.1     joerg 
   2122          1.1     joerg 	/* copy firmware image into NIC */
   2123          1.1     joerg 	for (; size >= 4; reg += 4, ucode += 4, size -= 4)
   2124          1.1     joerg 		rum_write(sc, reg, UGETDW(ucode));
   2125          1.1     joerg 
   2126          1.1     joerg 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
   2127          1.1     joerg 	req.bRequest = RT2573_MCU_CNTL;
   2128          1.1     joerg 	USETW(req.wValue, RT2573_MCU_RUN);
   2129          1.1     joerg 	USETW(req.wIndex, 0);
   2130          1.1     joerg 	USETW(req.wLength, 0);
   2131          1.1     joerg 
   2132          1.1     joerg 	error = usbd_do_request(sc->sc_udev, &req, NULL);
   2133          1.1     joerg 	if (error != 0) {
   2134          1.1     joerg 		printf("%s: could not run firmware: %s\n",
   2135          1.1     joerg 		    USBDEVNAME(sc->sc_dev), usbd_errstr(error));
   2136          1.1     joerg 	}
   2137          1.1     joerg 	return error;
   2138          1.1     joerg }
   2139          1.1     joerg 
   2140          1.1     joerg Static int
   2141          1.1     joerg rum_prepare_beacon(struct rum_softc *sc)
   2142          1.1     joerg {
   2143          1.1     joerg 	struct ieee80211com *ic = &sc->sc_ic;
   2144          1.1     joerg 	struct rum_tx_desc desc;
   2145          1.1     joerg 	struct mbuf *m0;
   2146          1.1     joerg 	int rate;
   2147          1.1     joerg 
   2148          1.1     joerg 	m0 = ieee80211_beacon_alloc(ic, ic->ic_bss, &sc->sc_bo);
   2149          1.1     joerg 	if (m0 == NULL) {
   2150          1.1     joerg 		printf("%s: could not allocate beacon frame\n",
   2151          1.1     joerg 		    sc->sc_dev.dv_xname);
   2152          1.1     joerg 		return ENOBUFS;
   2153          1.1     joerg 	}
   2154          1.1     joerg 
   2155          1.1     joerg 	/* send beacons at the lowest available rate */
   2156          1.1     joerg 	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
   2157          1.1     joerg 
   2158          1.1     joerg 	rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ,
   2159          1.1     joerg 	    m0->m_pkthdr.len, rate);
   2160          1.1     joerg 
   2161          1.1     joerg 	/* copy the first 24 bytes of Tx descriptor into NIC memory */
   2162          1.1     joerg 	rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
   2163          1.1     joerg 
   2164          1.1     joerg 	/* copy beacon header and payload into NIC memory */
   2165          1.1     joerg 	rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *),
   2166          1.1     joerg 	    m0->m_pkthdr.len);
   2167          1.1     joerg 
   2168          1.1     joerg 	m_freem(m0);
   2169          1.1     joerg 
   2170          1.1     joerg 	return 0;
   2171          1.1     joerg }
   2172          1.1     joerg 
   2173          1.1     joerg Static void
   2174          1.1     joerg rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
   2175          1.1     joerg {
   2176          1.1     joerg 	int i;
   2177          1.1     joerg 
   2178          1.1     joerg 	/* clear statistic registers (STA_CSR0 to STA_CSR5) */
   2179          1.1     joerg 	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
   2180          1.1     joerg 
   2181          1.1     joerg 	ieee80211_amrr_node_init(&sc->amrr, &sc->amn);
   2182          1.1     joerg 
   2183          1.1     joerg 	/* set rate to some reasonable initial value */
   2184          1.1     joerg 	for (i = ni->ni_rates.rs_nrates - 1;
   2185          1.1     joerg 	     i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72;
   2186          1.1     joerg 	     i--);
   2187          1.1     joerg 	ni->ni_txrate = i;
   2188          1.1     joerg 
   2189          1.1     joerg 	callout_reset(&sc->amrr_ch, hz, rum_amrr_timeout, sc);
   2190          1.1     joerg }
   2191          1.1     joerg 
   2192          1.1     joerg Static void
   2193          1.1     joerg rum_amrr_timeout(void *arg)
   2194          1.1     joerg {
   2195          1.1     joerg 	struct rum_softc *sc = arg;
   2196          1.1     joerg 	usb_device_request_t req;
   2197          1.1     joerg 	int s;
   2198          1.1     joerg 
   2199          1.1     joerg 	s = splusb();
   2200          1.1     joerg 
   2201          1.1     joerg 	/*
   2202          1.1     joerg 	 * Asynchronously read statistic registers (cleared by read).
   2203          1.1     joerg 	 */
   2204          1.1     joerg 	req.bmRequestType = UT_READ_VENDOR_DEVICE;
   2205          1.1     joerg 	req.bRequest = RT2573_READ_MULTI_MAC;
   2206          1.1     joerg 	USETW(req.wValue, 0);
   2207          1.1     joerg 	USETW(req.wIndex, RT2573_STA_CSR0);
   2208          1.1     joerg 	USETW(req.wLength, sizeof sc->sta);
   2209          1.1     joerg 
   2210          1.1     joerg 	usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc,
   2211          1.1     joerg 	    USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0,
   2212          1.1     joerg 	    rum_amrr_update);
   2213          1.1     joerg 	(void)usbd_transfer(sc->amrr_xfer);
   2214          1.1     joerg 
   2215          1.1     joerg 	splx(s);
   2216          1.1     joerg }
   2217          1.1     joerg 
   2218          1.1     joerg Static void
   2219          1.1     joerg rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv,
   2220          1.1     joerg     usbd_status status)
   2221          1.1     joerg {
   2222          1.1     joerg 	struct rum_softc *sc = (struct rum_softc *)priv;
   2223          1.1     joerg 	struct ifnet *ifp = sc->sc_ic.ic_ifp;
   2224          1.1     joerg 
   2225          1.1     joerg 	if (status != USBD_NORMAL_COMPLETION) {
   2226          1.1     joerg 		printf("%s: could not retrieve Tx statistics - cancelling "
   2227          1.1     joerg 		    "automatic rate control\n", USBDEVNAME(sc->sc_dev));
   2228          1.1     joerg 		return;
   2229          1.1     joerg 	}
   2230          1.1     joerg 
   2231          1.1     joerg 	/* count TX retry-fail as Tx errors */
   2232          1.1     joerg 	ifp->if_oerrors += le32toh(sc->sta[5]) >> 16;
   2233          1.1     joerg 
   2234          1.1     joerg 	sc->amn.amn_retrycnt =
   2235          1.1     joerg 	    (le32toh(sc->sta[4]) >> 16) +	/* TX one-retry ok count */
   2236          1.1     joerg 	    (le32toh(sc->sta[5]) & 0xffff) +	/* TX more-retry ok count */
   2237          1.1     joerg 	    (le32toh(sc->sta[5]) >> 16);	/* TX retry-fail count */
   2238          1.1     joerg 
   2239          1.1     joerg 	sc->amn.amn_txcnt =
   2240          1.1     joerg 	    sc->amn.amn_retrycnt +
   2241          1.1     joerg 	    (le32toh(sc->sta[4]) & 0xffff);	/* TX no-retry ok count */
   2242          1.1     joerg 
   2243          1.1     joerg 	ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn);
   2244          1.1     joerg 
   2245          1.1     joerg 	callout_reset(&sc->amrr_ch, hz, rum_amrr_timeout, sc);
   2246          1.1     joerg }
   2247          1.1     joerg 
   2248          1.1     joerg int
   2249          1.1     joerg rum_activate(device_ptr_t self, enum devact act)
   2250          1.1     joerg {
   2251          1.1     joerg 	switch (act) {
   2252          1.1     joerg 	case DVACT_ACTIVATE:
   2253          1.1     joerg 		return EOPNOTSUPP;
   2254          1.1     joerg 
   2255          1.1     joerg 	case DVACT_DEACTIVATE:
   2256          1.1     joerg 		/*if_deactivate(&sc->sc_ic.ic_if);*/
   2257          1.1     joerg 		break;
   2258          1.1     joerg 	}
   2259          1.1     joerg 
   2260          1.1     joerg 	return 0;
   2261          1.1     joerg }
   2262