From owner-freebsd-usb@FreeBSD.ORG Mon Dec 16 08:20:01 2013 Return-Path: Delivered-To: freebsd-usb@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 324D4F4F for ; Mon, 16 Dec 2013 08:20:01 +0000 (UTC) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 1B3121493 for ; Mon, 16 Dec 2013 08:20:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.7/8.14.7) with ESMTP id rBG8K1J1082602 for ; Mon, 16 Dec 2013 08:20:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.7/8.14.7/Submit) id rBG8K1rJ082601; Mon, 16 Dec 2013 08:20:01 GMT (envelope-from gnats) Date: Mon, 16 Dec 2013 08:20:01 GMT Message-Id: <201312160820.rBG8K1rJ082601@freefall.freebsd.org> To: freebsd-usb@FreeBSD.org Cc: From: dfilter@FreeBSD.ORG (dfilter service) Subject: Re: usb/182936: commit references a PR X-BeenThere: freebsd-usb@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list Reply-To: dfilter service List-Id: FreeBSD support for USB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 16 Dec 2013 08:20:01 -0000 The following reply was made to PR usb/182936; it has been noted by GNATS. From: dfilter@FreeBSD.ORG (dfilter service) To: bug-followup@FreeBSD.org Cc: Subject: Re: usb/182936: commit references a PR Date: Mon, 16 Dec 2013 08:10:48 +0000 (UTC) Author: hselasky Date: Mon Dec 16 08:10:38 2013 New Revision: 259453 URL: http://svnweb.freebsd.org/changeset/base/259453 Log: MFC r238274, r246752, r256720, r256721, r256722, r256955, r257409 r257429, r257435, r257712, r257732, r257743, r257748, r257955 r257957, r257958, r258082, r258641, r258643, r258732, r258733, r258840, r258919, r258921, r259029, r259030, r259031, r259032 and r259046: - Add support for the MediaTek/Ralink RT5370/RT5372 chipset. - Various minor USB WLAN fixes and improvements. PR: usb/182936 Modified: stable/10/share/man/man4/run.4 stable/10/share/man/man4/runfw.4 stable/10/sys/dev/usb/usbdevs stable/10/sys/dev/usb/wlan/if_rsu.c stable/10/sys/dev/usb/wlan/if_rum.c stable/10/sys/dev/usb/wlan/if_run.c stable/10/sys/dev/usb/wlan/if_runreg.h stable/10/sys/dev/usb/wlan/if_runvar.h stable/10/sys/dev/usb/wlan/if_uath.c stable/10/sys/dev/usb/wlan/if_upgt.c stable/10/sys/dev/usb/wlan/if_ural.c stable/10/sys/dev/usb/wlan/if_urtw.c stable/10/sys/dev/usb/wlan/if_urtwn.c stable/10/sys/dev/usb/wlan/if_zyd.c Directory Properties: stable/10/ (props changed) Modified: stable/10/share/man/man4/run.4 ============================================================================== --- stable/10/share/man/man4/run.4 Mon Dec 16 06:56:38 2013 (r259452) +++ stable/10/share/man/man4/run.4 Mon Dec 16 08:10:38 2013 (r259453) @@ -16,7 +16,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 9, 2012 +.Dd November 11, 2013 .Dt RUN 4 .Os .Sh NAME @@ -52,7 +52,7 @@ runfw_load="YES" The .Nm driver supports USB 2.0 wireless adapters based on the Ralink RT2700U, -RT2800U and RT3000U chipsets. +RT2800U, RT3000U and RT3900E chipsets. .Pp The RT2700U chipset consists of two integrated chips, an RT2770 MAC/BBP and an RT2720 (1T2R) or RT2750 (dual-band 1T2R) radio transceiver. @@ -64,6 +64,9 @@ The RT3000U is a single-chip solution ba an RT3020 (1T1R), RT3021 (1T2R) or RT3022 (2T2R) single-band radio transceiver. .Pp +The RT3900E is a single-chip solution based on an RT5390 MAC/BBP and +an RT5370 (1T1R) or RT5372 (2T2R) single-band radio transceiver. +.Pp These are the modes the .Nm driver can operate in: @@ -129,7 +132,8 @@ driver supports the following wireless a .It Corega CG-WLUSB300AGN .It Corega CG-WLUSB300GNM .It D-Link DWA-130 rev B1 -.It D-Link DWA-140 rev B1, B2 +.It D-Link DWA-140 rev B1, B2, B3 +.It D-Link DWA-160 rev B2 .It DrayTek Vigor N61 .It Edimax EW-7711UAn .It Edimax EW-7711UTn @@ -156,6 +160,8 @@ driver supports the following wireless a .It SMC SMCWUSBS-N2 .It Sweex LW303 .It Sweex LW313 +.It TP-LINK TL-WDN3200 +.It TP-LINK TL-WN727N v3 .It Unex DNUR-81 .It Unex DNUR-82 .It ZyXEL NWD210N Modified: stable/10/share/man/man4/runfw.4 ============================================================================== --- stable/10/share/man/man4/runfw.4 Mon Dec 16 06:56:38 2013 (r259452) +++ stable/10/share/man/man4/runfw.4 Mon Dec 16 08:10:38 2013 (r259453) @@ -18,7 +18,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 12, 2011 +.Dd November 11, 2013 .Dt RUNFW 4 .Os .Sh NAME @@ -43,7 +43,7 @@ runfw_load="YES" .Ed .Sh DESCRIPTION This module provides firmware sets for the Ralink RT2700U, -RT2800U and RT3000U chip based USB WiFi adapters. +RT2800U, RT3000U and RT3900E chip based USB WiFi adapters. Please read Ralink's license, src/sys/contrib/dev/run/LICENSE. .Sh SEE ALSO .Xr run 4 , Modified: stable/10/sys/dev/usb/usbdevs ============================================================================== --- stable/10/sys/dev/usb/usbdevs Mon Dec 16 06:56:38 2013 (r259452) +++ stable/10/sys/dev/usb/usbdevs Mon Dec 16 08:10:38 2013 (r259453) @@ -1549,6 +1549,8 @@ product DLINK DWLG122 0x3c00 DWL-G122 b product DLINK DUBE100B1 0x3c05 DUB-E100 rev B1 product DLINK RT2870 0x3c09 RT2870 product DLINK RT3072 0x3c0a RT3072 +product DLINK DWA140B3 0x3c15 DWA-140 rev B3 +product DLINK DWA160B2 0x3c1a DWA-160 rev B2 product DLINK DWA127 0x3c1b DWA-127 Wireless Adapter product DLINK DSB650C 0x4000 10Mbps Ethernet product DLINK DSB650TX1 0x4001 10/100 Ethernet @@ -3572,6 +3574,7 @@ product RALINK RT3072 0x3072 RT3072 product RALINK RT3370 0x3370 RT3370 product RALINK RT3572 0x3572 RT3572 product RALINK RT5370 0x5370 RT5370 +product RALINK RT5572 0x5572 RT5572 product RALINK RT8070 0x8070 RT8070 product RALINK RT2570_3 0x9020 RT2500USB Wireless Adapter product RALINK RT2573_2 0x9021 RT2501USB Wireless Adapter Modified: stable/10/sys/dev/usb/wlan/if_rsu.c ============================================================================== --- stable/10/sys/dev/usb/wlan/if_rsu.c Mon Dec 16 06:56:38 2013 (r259452) +++ stable/10/sys/dev/usb/wlan/if_rsu.c Mon Dec 16 08:10:38 2013 (r259453) @@ -480,8 +480,13 @@ rsu_vap_create(struct ieee80211com *ic, if (uvp == NULL) return (NULL); vap = &uvp->vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags, bssid, mac); + + if (ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags, bssid, mac) != 0) { + /* out of memory */ + free(uvp, M_80211_VAP); + return (NULL); + } /* override state transition machine */ uvp->newstate = vap->iv_newstate; @@ -1153,7 +1158,7 @@ rsu_event_survey(struct rsu_softc *sc, u wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON; wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(uint16_t *)wh->i_dur = 0; + USETW(wh->i_dur, 0); IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr); IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr); IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr); Modified: stable/10/sys/dev/usb/wlan/if_rum.c ============================================================================== --- stable/10/sys/dev/usb/wlan/if_rum.c Mon Dec 16 06:56:38 2013 (r259452) +++ stable/10/sys/dev/usb/wlan/if_rum.c Mon Dec 16 08:10:38 2013 (r259453) @@ -604,8 +604,13 @@ rum_vap_create(struct ieee80211com *ic, return NULL; vap = &rvp->vap; /* enable s/w bmiss handling for sta mode */ - ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + + if (ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags | IEEE80211_CLONE_NOBEACONS, bssid, mac) != 0) { + /* out of memory */ + free(rvp, M_80211_VAP); + return (NULL); + } /* override state transition machine */ rvp->newstate = vap->iv_newstate; @@ -1131,7 +1136,7 @@ rum_tx_mgt(struct rum_softc *sc, struct dur = ieee80211_ack_duration(ic->ic_rt, tp->mgmtrate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); - *(uint16_t *)wh->i_dur = htole16(dur); + USETW(wh->i_dur, dur); /* tell hardware to add timestamp for probe responses */ if ((wh->i_fc[0] & @@ -1275,7 +1280,7 @@ rum_tx_data(struct rum_softc *sc, struct dur = ieee80211_ack_duration(ic->ic_rt, rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); - *(uint16_t *)wh->i_dur = htole16(dur); + USETW(wh->i_dur, dur); } rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate); Modified: stable/10/sys/dev/usb/wlan/if_run.c ============================================================================== --- stable/10/sys/dev/usb/wlan/if_run.c Mon Dec 16 06:56:38 2013 (r259452) +++ stable/10/sys/dev/usb/wlan/if_run.c Mon Dec 16 08:10:38 2013 (r259453) @@ -2,6 +2,7 @@ * Copyright (c) 2008,2010 Damien Bergamini * ported to FreeBSD by Akinori Furukoshi * USB Consulting, Hans Petter Selasky + * Copyright (c) 2013 Kevin Lo * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -20,7 +21,7 @@ __FBSDID("$FreeBSD$"); /*- - * Ralink Technology RT2700U/RT2800U/RT3000U chipset driver. + * Ralink Technology RT2700U/RT2800U/RT3000U/RT3900E chipset driver. * http://www.ralinktech.com/ */ @@ -74,8 +75,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define N(_a) ((int)(sizeof((_a)) / sizeof((_a)[0]))) - #ifdef USB_DEBUG #define RUN_DEBUG #endif @@ -173,6 +172,8 @@ static const STRUCT_USB_HOST_ID run_devs RUN_DEV(DLINK, RT2870), RUN_DEV(DLINK, RT3072), RUN_DEV(DLINK, DWA127), + RUN_DEV(DLINK, DWA140B3), + RUN_DEV(DLINK, DWA160B2), RUN_DEV(DLINK2, DWA130), RUN_DEV(DLINK2, RT2870_1), RUN_DEV(DLINK2, RT2870_2), @@ -256,6 +257,8 @@ static const STRUCT_USB_HOST_ID run_devs RUN_DEV(RALINK, RT3072), RUN_DEV(RALINK, RT3370), RUN_DEV(RALINK, RT3572), + RUN_DEV(RALINK, RT5370), + RUN_DEV(RALINK, RT5572), RUN_DEV(RALINK, RT8070), RUN_DEV(SAMSUNG, WIS09ABGN), RUN_DEV(SAMSUNG2, RT2870_1), @@ -319,7 +322,7 @@ static usb_callback_t run_bulk_tx_callba static usb_callback_t run_bulk_tx_callback5; static void run_bulk_tx_callbackN(struct usb_xfer *xfer, - usb_error_t error, unsigned int index); + usb_error_t error, u_int index); static struct ieee80211vap *run_vap_create(struct ieee80211com *, const char [IFNAMSIZ], int, enum ieee80211_opmode, int, const uint8_t [IEEE80211_ADDR_LEN], @@ -343,13 +346,13 @@ static int run_write_region_1(struct run static int run_set_region_4(struct run_softc *, uint16_t, uint32_t, int); static int run_efuse_read_2(struct run_softc *, uint16_t, uint16_t *); static int run_eeprom_read_2(struct run_softc *, uint16_t, uint16_t *); -static int run_rt2870_rf_write(struct run_softc *, uint8_t, uint32_t); +static int run_rt2870_rf_write(struct run_softc *, uint32_t); static int run_rt3070_rf_read(struct run_softc *, uint8_t, uint8_t *); static int run_rt3070_rf_write(struct run_softc *, uint8_t, uint8_t); static int run_bbp_read(struct run_softc *, uint8_t, uint8_t *); static int run_bbp_write(struct run_softc *, uint8_t, uint8_t); static int run_mcu_cmd(struct run_softc *, uint8_t, uint16_t); -static const char *run_get_rf(int); +static const char *run_get_rf(uint16_t); static int run_read_eeprom(struct run_softc *); static struct ieee80211_node *run_node_alloc(struct ieee80211vap *, const uint8_t mac[IEEE80211_ADDR_LEN]); @@ -361,7 +364,7 @@ static void run_key_update_begin(struct static void run_key_update_end(struct ieee80211vap *); static void run_key_set_cb(void *); static int run_key_set(struct ieee80211vap *, struct ieee80211_key *, - const uint8_t mac[IEEE80211_ADDR_LEN]); + const uint8_t mac[IEEE80211_ADDR_LEN]); static void run_key_delete_cb(void *); static int run_key_delete(struct ieee80211vap *, struct ieee80211_key *); static void run_ratectl_to(void *); @@ -393,6 +396,8 @@ static void run_set_rx_antenna(struct ru static void run_rt2870_set_chan(struct run_softc *, u_int); static void run_rt3070_set_chan(struct run_softc *, u_int); static void run_rt3572_set_chan(struct run_softc *, u_int); +static void run_rt5390_set_chan(struct run_softc *, u_int); +static void run_rt5592_set_chan(struct run_softc *, u_int); static int run_set_chan(struct run_softc *, struct ieee80211_channel *); static void run_set_channel(struct ieee80211com *); static void run_scan_start(struct ieee80211com *); @@ -416,16 +421,19 @@ static void run_update_mcast(struct ifne static int8_t run_rssi2dbm(struct run_softc *, uint8_t, uint8_t); static void run_update_promisc_locked(struct ifnet *); static void run_update_promisc(struct ifnet *); +static void run_rt5390_bbp_init(struct run_softc *); static int run_bbp_init(struct run_softc *); static int run_rt3070_rf_init(struct run_softc *); +static void run_rt5390_rf_init(struct run_softc *); static int run_rt3070_filter_calib(struct run_softc *, uint8_t, uint8_t, uint8_t *); static void run_rt3070_rf_setup(struct run_softc *); static int run_txrx_enable(struct run_softc *); +static void run_adjust_freq_offset(struct run_softc *); static void run_init(void *); static void run_init_locked(struct run_softc *); static void run_stop(void *); -static void run_delay(struct run_softc *, unsigned int); +static void run_delay(struct run_softc *, u_int); static const struct { uint16_t reg; @@ -439,6 +447,25 @@ static const struct { uint8_t val; } rt2860_def_bbp[] = { RT2860_DEF_BBP +},rt5390_def_bbp[] = { + RT5390_DEF_BBP +},rt5592_def_bbp[] = { + RT5592_DEF_BBP +}; + +/* + * Default values for BBP register R196 for RT5592. + */ +static const uint8_t rt5592_bbp_r196[] = { + 0xe0, 0x1f, 0x38, 0x32, 0x08, 0x28, 0x19, 0x0a, 0xff, 0x00, + 0x16, 0x10, 0x10, 0x0b, 0x36, 0x2c, 0x26, 0x24, 0x42, 0x36, + 0x30, 0x2d, 0x4c, 0x46, 0x3d, 0x40, 0x3e, 0x42, 0x3d, 0x40, + 0x3c, 0x34, 0x2c, 0x2f, 0x3c, 0x35, 0x2e, 0x2a, 0x49, 0x41, + 0x36, 0x31, 0x30, 0x30, 0x0e, 0x0d, 0x28, 0x21, 0x1c, 0x16, + 0x50, 0x4a, 0x43, 0x40, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7d, 0x14, 0x32, 0x2c, 0x36, 0x4c, 0x43, 0x2c, + 0x2e, 0x36, 0x30, 0x6e }; static const struct rfprog { @@ -454,6 +481,15 @@ struct { RT3070_RF3052 }; +static const struct rt5592_freqs { + uint16_t n; + uint8_t k, m, r; +} rt5592_freqs_20mhz[] = { + RT5592_RF5592_20MHZ +},rt5592_freqs_40mhz[] = { + RT5592_RF5592_40MHZ +}; + static const struct { uint8_t reg; uint8_t val; @@ -461,6 +497,25 @@ static const struct { RT3070_DEF_RF },rt3572_def_rf[] = { RT3572_DEF_RF +},rt5390_def_rf[] = { + RT5390_DEF_RF +},rt5392_def_rf[] = { + RT5392_DEF_RF +},rt5592_def_rf[] = { + RT5592_DEF_RF +},rt5592_2ghz_def_rf[] = { + RT5592_2GHZ_DEF_RF +},rt5592_5ghz_def_rf[] = { + RT5592_5GHZ_DEF_RF +}; + +static const struct { + u_int firstchan; + u_int lastchan; + uint8_t reg; + uint8_t val; +} rt5592_chan_5ghz[] = { + RT5592_CHAN_5GHZ }; static const struct usb_config run_config[RUN_N_XFER] = { @@ -557,7 +612,7 @@ run_attach(device_t self) struct ieee80211com *ic; struct ifnet *ifp; uint32_t ver; - int i, ntries, error; + int ntries, error; uint8_t iface_index, bands; device_set_usb_desc(self); @@ -654,27 +709,11 @@ run_attach(device_t self) bands = 0; setbit(&bands, IEEE80211_MODE_11B); setbit(&bands, IEEE80211_MODE_11G); + if (sc->rf_rev == RT2860_RF_2750 || sc->rf_rev == RT2860_RF_2850 || + sc->rf_rev == RT3070_RF_3052 || sc->rf_rev == RT5592_RF_5592) + setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); - /* - * Do this by own because h/w supports - * more channels than ieee80211_init_channels() - */ - if (sc->rf_rev == RT2860_RF_2750 || - sc->rf_rev == RT2860_RF_2850 || - sc->rf_rev == RT3070_RF_3052) { - /* set supported .11a rates */ - for (i = 14; i < N(rt2860_rf2850); i++) { - uint8_t chan = rt2860_rf2850[i].chan; - ic->ic_channels[ic->ic_nchans].ic_freq = - ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A); - ic->ic_channels[ic->ic_nchans].ic_ieee = chan; - ic->ic_channels[ic->ic_nchans].ic_flags = IEEE80211_CHAN_A; - ic->ic_channels[ic->ic_nchans].ic_extieee = 0; - ic->ic_nchans++; - } - } - ieee80211_ifattach(ic, sc->sc_bssid); ic->ic_scan_start = run_scan_start; @@ -699,7 +738,7 @@ run_attach(device_t self) TASK_INIT(&sc->cmdq_task, 0, run_cmdq_cb, sc); TASK_INIT(&sc->ratectl_task, 0, run_ratectl_cb, sc); - callout_init((struct callout *)&sc->ratectl_ch, 1); + usb_callout_init_mtx(&sc->ratectl_ch, &sc->sc_mtx, 0); if (bootverbose) ieee80211_announce(ic); @@ -803,7 +842,13 @@ run_vap_create(struct ieee80211com *ic, if (rvp == NULL) return (NULL); vap = &rvp->vap; - ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + + if (ieee80211_vap_setup(ic, vap, name, unit, + opmode, flags, bssid, mac) != 0) { + /* out of memory */ + free(rvp, M_80211_VAP); + return (NULL); + } vap->iv_key_update_begin = run_key_update_begin; vap->iv_key_update_end = run_key_update_end; @@ -1009,13 +1054,12 @@ run_load_microcode(struct run_softc *sc) /* cheap sanity check */ temp = fw->data; bytes = *temp; - if (bytes != be64toh(0xffffff0210280210)) { + if (bytes != be64toh(0xffffff0210280210ULL)) { device_printf(sc->sc_dev, "firmware checksum failed\n"); error = EINVAL; goto fail; } - run_read(sc, RT2860_ASIC_VER_ID, &tmp); /* write microcode image */ run_write_region_1(sc, RT2870_FW_BASE, base, 4096); run_write(sc, RT2860_H2M_MAILBOX_CID, 0xffffffff); @@ -1062,7 +1106,7 @@ fail: return (error); } -int +static int run_reset(struct run_softc *sc) { usb_device_request_t req; @@ -1164,13 +1208,32 @@ run_write_region_1(struct run_softc *sc, return (error); #else usb_device_request_t req; + int error = 0; - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = RT2870_WRITE_REGION_1; - USETW(req.wValue, 0); - USETW(req.wIndex, reg); - USETW(req.wLength, len); - return (run_do_request(sc, &req, buf)); + /* + * NOTE: It appears the WRITE_REGION_1 command cannot be + * passed a huge amount of data, which will crash the + * firmware. Limit amount of data passed to 64-bytes at a + * time. + */ + while (len > 0) { + int delta = 64; + if (delta > len) + delta = len; + + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = RT2870_WRITE_REGION_1; + USETW(req.wValue, 0); + USETW(req.wIndex, reg); + USETW(req.wLength, delta); + error = run_do_request(sc, &req, __DECONST(uint8_t *, buf)); + if (error != 0) + break; + reg += delta; + buf += delta; + len -= delta; + } + return (error); #endif } @@ -1260,7 +1323,7 @@ run_srom_read(struct run_softc *sc, uint } static int -run_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val) +run_rt2870_rf_write(struct run_softc *sc, uint32_t val) { uint32_t tmp; int error, ntries; @@ -1274,10 +1337,7 @@ run_rt2870_rf_write(struct run_softc *sc if (ntries == 10) return (ETIMEDOUT); - /* RF registers are 24-bit on the RT2860 */ - tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT | - (val & 0x3fffff) << 2 | (reg & 3); - return (run_write(sc, RT2860_RF_CSR_CFG0, tmp)); + return (run_write(sc, RT2860_RF_CSR_CFG0, val)); } static int @@ -1428,7 +1488,7 @@ b4inc(uint32_t b32, int8_t delta) } static const char * -run_get_rf(int rev) +run_get_rf(uint16_t rev) { switch (rev) { case RT2860_RF_2820: return "RT2820"; @@ -1440,11 +1500,14 @@ run_get_rf(int rev) case RT3070_RF_3021: return "RT3021"; case RT3070_RF_3022: return "RT3022"; case RT3070_RF_3052: return "RT3052"; + case RT5592_RF_5592: return "RT5592"; + case RT5390_RF_5370: return "RT5370"; + case RT5390_RF_5372: return "RT5372"; } return ("unknown"); } -int +static int run_read_eeprom(struct run_softc *sc) { int8_t delta_2ghz, delta_5ghz; @@ -1476,21 +1539,25 @@ run_read_eeprom(struct run_softc *sc) sc->sc_bssid[4] = val & 0xff; sc->sc_bssid[5] = val >> 8; - /* read vender BBP settings */ - for (i = 0; i < 10; i++) { - run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val); - sc->bbp[i].val = val & 0xff; - sc->bbp[i].reg = val >> 8; - DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, sc->bbp[i].val); - } - if (sc->mac_ver >= 0x3071) { - /* read vendor RF settings */ + if (sc->mac_ver < 0x5390) { + /* read vender BBP settings */ for (i = 0; i < 10; i++) { - run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, &val); - sc->rf[i].val = val & 0xff; - sc->rf[i].reg = val >> 8; - DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg, - sc->rf[i].val); + run_srom_read(sc, RT2860_EEPROM_BBP_BASE + i, &val); + sc->bbp[i].val = val & 0xff; + sc->bbp[i].reg = val >> 8; + DPRINTF("BBP%d=0x%02x\n", sc->bbp[i].reg, + sc->bbp[i].val); + } + if (sc->mac_ver >= 0x3071) { + /* read vendor RF settings */ + for (i = 0; i < 10; i++) { + run_srom_read(sc, RT3071_EEPROM_RF_BASE + i, + &val); + sc->rf[i].val = val & 0xff; + sc->rf[i].reg = val >> 8; + DPRINTF("RF%d=0x%02x\n", sc->rf[i].reg, + sc->rf[i].val); + } } } @@ -1516,7 +1583,11 @@ run_read_eeprom(struct run_softc *sc) sc->leds, sc->led[0], sc->led[1], sc->led[2]); /* read RF information */ - run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); + if (sc->mac_ver == 0x5390 || sc->mac_ver ==0x5392) + run_srom_read(sc, 0x00, &val); + else + run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); + if (val == 0xffff) { DPRINTF("invalid EEPROM antenna info, using default\n"); if (sc->mac_ver == 0x3572) { @@ -1536,11 +1607,15 @@ run_read_eeprom(struct run_softc *sc) sc->nrxchains = 2; } } else { - sc->rf_rev = (val >> 8) & 0xf; + if (sc->mac_ver == 0x5390 || sc->mac_ver ==0x5392) { + sc->rf_rev = val; + run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); + } else + sc->rf_rev = (val >> 8) & 0xf; sc->ntxchains = (val >> 4) & 0xf; sc->nrxchains = val & 0xf; } - DPRINTF("EEPROM RF rev=0x%02x chains=%dT%dR\n", + DPRINTF("EEPROM RF rev=0x%04x chains=%dT%dR\n", sc->rf_rev, sc->ntxchains, sc->nrxchains); /* check if RF supports automatic Tx access gain control */ @@ -1564,16 +1639,29 @@ run_read_eeprom(struct run_softc *sc) sc->txpow1[i + 0] = (int8_t)(val & 0xff); sc->txpow1[i + 1] = (int8_t)(val >> 8); - run_srom_read(sc, RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val); - sc->txpow2[i + 0] = (int8_t)(val & 0xff); - sc->txpow2[i + 1] = (int8_t)(val >> 8); + if (sc->mac_ver != 0x5390) { + run_srom_read(sc, + RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2, &val); + sc->txpow2[i + 0] = (int8_t)(val & 0xff); + sc->txpow2[i + 1] = (int8_t)(val >> 8); + } } /* fix broken Tx power entries */ for (i = 0; i < 14; i++) { - if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) - sc->txpow1[i] = 5; - if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) - sc->txpow2[i] = 5; + if (sc->mac_ver >= 0x5390) { + if (sc->txpow1[i] < 0 || sc->txpow1[i] > 27) + sc->txpow1[i] = 5; + } else { + if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) + sc->txpow1[i] = 5; + } + if (sc->mac_ver > 0x5390) { + if (sc->txpow2[i] < 0 || sc->txpow2[i] > 27) + sc->txpow2[i] = 5; + } else if (sc->mac_ver < 0x5390) { + if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) + sc->txpow2[i] = 5; + } DPRINTF("chan %d: power1=%d, power2=%d\n", rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i]); } @@ -1588,11 +1676,13 @@ run_read_eeprom(struct run_softc *sc) sc->txpow2[i + 15] = (int8_t)(val >> 8); } /* fix broken Tx power entries */ - for (i = 0; i < 40; i++) { - if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15) - sc->txpow1[14 + i] = 5; - if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15) - sc->txpow2[14 + i] = 5; + for (i = 0; i < 40; i++ ) { + if (sc->mac_ver != 0x5592) { + if (sc->txpow1[14 + i] < -7 || sc->txpow1[14 + i] > 15) + sc->txpow1[14 + i] = 5; + if (sc->txpow2[14 + i] < -7 || sc->txpow2[14 + i] > 15) + sc->txpow2[14 + i] = 5; + } DPRINTF("chan %d: power1=%d, power2=%d\n", rt2860_rf2850[14 + i].chan, sc->txpow1[14 + i], sc->txpow2[14 + i]); @@ -2236,8 +2326,10 @@ run_ratectl_cb(void *arg, int pending) ieee80211_iterate_nodes(&ic->ic_sta, run_iter_func, sc); } + RUN_LOCK(sc); if(sc->ratectl_run != RUN_RATECTL_OFF) usb_callout_reset(&sc->ratectl_ch, hz, run_ratectl_to, sc); + RUN_UNLOCK(sc); } static void @@ -2472,12 +2564,15 @@ run_rx_frame(struct run_softc *sc, struc struct rt2870_rxd *rxd; struct rt2860_rxwi *rxwi; uint32_t flags; - uint16_t len, phy; + uint16_t len, rxwisize; uint8_t ant, rssi; int8_t nf; rxwi = mtod(m, struct rt2860_rxwi *); len = le16toh(rxwi->len) & 0xfff; + rxwisize = (sc->mac_ver == 0x5592) ? + sizeof(struct rt2860_rxwi) + sizeof(uint64_t) : + sizeof(struct rt2860_rxwi); if (__predict_false(len > dmalen)) { m_freem(m); ifp->if_ierrors++; @@ -2495,8 +2590,8 @@ run_rx_frame(struct run_softc *sc, struc return; } - m->m_data += sizeof(struct rt2860_rxwi); - m->m_pkthdr.len = m->m_len -= sizeof(struct rt2860_rxwi); + m->m_data += rxwisize; + m->m_pkthdr.len = m->m_len -= rxwisize; wh = mtod(m, struct ieee80211_frame *); @@ -2516,7 +2611,8 @@ run_rx_frame(struct run_softc *sc, struc if (__predict_false(flags & RT2860_RX_MICERR)) { /* report MIC failures to net80211 for TKIP */ if (ni != NULL) - ieee80211_notify_michael_failure(ni->ni_vap, wh, rxwi->keyidx); + ieee80211_notify_michael_failure(ni->ni_vap, wh, + rxwi->keyidx); m_freem(m); ifp->if_ierrors++; DPRINTF("MIC error. Someone is lying.\n"); @@ -2539,6 +2635,7 @@ run_rx_frame(struct run_softc *sc, struc if (__predict_false(ieee80211_radiotap_active(ic))) { struct run_rx_radiotap_header *tap = &sc->sc_rxtap; + uint16_t phy; tap->wr_flags = 0; tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); @@ -2583,8 +2680,13 @@ run_bulk_rx_callback(struct usb_xfer *xf struct mbuf *m = NULL; struct mbuf *m0; uint32_t dmalen; + uint16_t rxwisize; int xferlen; + rxwisize = (sc->mac_ver == 0x5592) ? + sizeof(struct rt2860_rxwi) + sizeof(uint64_t) : + sizeof(struct rt2860_rxwi); + usbd_xfer_status(xfer, &xferlen, NULL, NULL, NULL); switch (USB_GET_STATE(xfer)) { @@ -2592,8 +2694,8 @@ run_bulk_rx_callback(struct usb_xfer *xf DPRINTFN(15, "rx done, actlen=%d\n", xferlen); - if (xferlen < (int)(sizeof(uint32_t) + - sizeof(struct rt2860_rxwi) + sizeof(struct rt2870_rxd))) { + if (xferlen < (int)(sizeof(uint32_t) + rxwisize + + sizeof(struct rt2870_rxd))) { DPRINTF("xfer too short %d\n", xferlen); goto tr_setup; } @@ -2675,6 +2777,7 @@ tr_setup: m->m_data += 4; m->m_pkthdr.len = m->m_len -= 4; run_rx_frame(sc, m, dmalen); + m = NULL; /* don't free source buffer */ break; } @@ -2696,6 +2799,9 @@ tr_setup: m->m_pkthdr.len = m->m_len -= dmalen + 8; } + /* make sure we free the source buffer, if any */ + m_freem(m); + RUN_LOCK(sc); } @@ -2723,7 +2829,7 @@ run_tx_free(struct run_endpoint_queue *p } static void -run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, unsigned int index) +run_bulk_tx_callbackN(struct usb_xfer *xfer, usb_error_t error, u_int index) { struct run_softc *sc = usbd_xfer_softc(xfer); struct ifnet *ifp = sc->sc_ifp; @@ -2763,8 +2869,10 @@ tr_setup: STAILQ_REMOVE_HEAD(&pq->tx_qh, next); m = data->m; + size = (sc->mac_ver == 0x5592) ? + RUN_MAX_TXSZ + sizeof(uint32_t) : RUN_MAX_TXSZ; if ((m->m_pkthdr.len + - sizeof(data->desc) + 3 + 8) > RUN_MAX_TXSZ) { + sizeof(data->desc) + 3 + 8) > size) { DPRINTF("data overflow, %u bytes\n", m->m_pkthdr.len); @@ -2776,7 +2884,8 @@ tr_setup: } pc = usbd_xfer_get_frame(xfer, 0); - size = sizeof(data->desc); + size = (sc->mac_ver == 0x5592) ? + sizeof(data->desc) + sizeof(uint32_t) : sizeof(data->desc); usbd_copy_in(pc, 0, &data->desc, size); usbd_m_copy_in(pc, size, m, 0, m->m_pkthdr.len); size += m->m_pkthdr.len; @@ -2791,9 +2900,8 @@ tr_setup: vap = data->ni->ni_vap; if (ieee80211_radiotap_active_vap(vap)) { struct run_tx_radiotap_header *tap = &sc->sc_txtap; - struct rt2860_txwi *txwi = + struct rt2860_txwi *txwi = (struct rt2860_txwi *)(&data->desc + sizeof(struct rt2870_txd)); - tap->wt_flags = 0; tap->wt_rate = rt2860_rates[data->ridx].rate; tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); @@ -2903,7 +3011,7 @@ run_set_tx_desc(struct run_softc *sc, st struct ieee80211_frame *wh; struct rt2870_txd *txd; struct rt2860_txwi *txwi; - uint16_t xferlen; + uint16_t xferlen, txwisize; uint16_t mcs; uint8_t ridx = data->ridx; uint8_t pad; @@ -2911,7 +3019,9 @@ run_set_tx_desc(struct run_softc *sc, st /* get MCS code from rate index */ mcs = rt2860_rates[ridx].mcs; - xferlen = sizeof(*txwi) + m->m_pkthdr.len; + txwisize = (sc->mac_ver == 0x5592) ? + sizeof(*txwi) + sizeof(uint32_t) : sizeof(*txwi); + xferlen = txwisize + m->m_pkthdr.len; /* roundup to 32-bit alignment */ xferlen = (xferlen + 3) & ~3; @@ -3037,7 +3147,7 @@ run_tx(struct run_softc *sc, struct mbuf dur = rt2860_rates[ctl_ridx].sp_ack_dur; else dur = rt2860_rates[ctl_ridx].lp_ack_dur; - *(uint16_t *)wh->i_dur = htole16(dur); + USETW(wh->i_dur, dur); } /* reserve slots for mgmt packets, just in case */ @@ -3054,12 +3164,12 @@ run_tx(struct run_softc *sc, struct mbuf txd->flags = qflags; txwi = (struct rt2860_txwi *)(txd + 1); txwi->xflags = xflags; - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) txwi->wcid = 0; - } else { + else txwi->wcid = (vap->iv_opmode == IEEE80211_M_STA) ? 1 : RUN_AID2WCID(ni->ni_associd); - } + /* clear leftover garbage bits */ txwi->flags = 0; txwi->txop = 0; @@ -3117,9 +3227,9 @@ run_tx(struct run_softc *sc, struct mbuf usbd_transfer_start(sc->sc_xfer[qid]); - DPRINTFN(8, "sending data frame len=%d rate=%d qid=%d\n", m->m_pkthdr.len + - (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)), - rt2860_rates[ridx].rate, qid); + DPRINTFN(8, "sending data frame len=%d rate=%d qid=%d\n", + m->m_pkthdr.len + (int)(sizeof(struct rt2870_txd) + + sizeof(struct rt2860_txwi)), rt2860_rates[ridx].rate, qid); return (0); } @@ -3156,7 +3266,7 @@ run_tx_mgt(struct run_softc *sc, struct dur = ieee80211_ack_duration(ic->ic_rt, rt2860_rates[ridx].rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); - *(uint16_t *)wh->i_dur = htole16(dur); + USETW(wh->i_dur, dur); } if (sc->sc_epq[0].tx_nfree == 0) { @@ -3183,7 +3293,7 @@ run_tx_mgt(struct run_softc *sc, struct run_set_tx_desc(sc, data); DPRINTFN(10, "sending mgt frame len=%d rate=%d\n", m->m_pkthdr.len + - (int)(sizeof (struct rt2870_txd) + sizeof (struct rt2860_rxwi)), + (int)(sizeof(struct rt2870_txd) + sizeof(struct rt2860_txwi)), rt2860_rates[ridx].rate); STAILQ_INSERT_TAIL(&sc->sc_epq[0].tx_qh, data, next); @@ -3513,18 +3623,63 @@ run_select_chan_group(struct run_softc * run_bbp_write(sc, 62, 0x37 - sc->lna[group]); run_bbp_write(sc, 63, 0x37 - sc->lna[group]); run_bbp_write(sc, 64, 0x37 - sc->lna[group]); - run_bbp_write(sc, 86, 0x00); + if (sc->mac_ver < 0x3572) + run_bbp_write(sc, 86, 0x00); if (group == 0) { if (sc->ext_2ghz_lna) { - run_bbp_write(sc, 82, 0x62); - run_bbp_write(sc, 75, 0x46); + if (sc->mac_ver >= 0x5390) + run_bbp_write(sc, 75, 0x52); + else { + run_bbp_write(sc, 82, 0x62); + run_bbp_write(sc, 75, 0x46); + } } else { - run_bbp_write(sc, 82, 0x84); - run_bbp_write(sc, 75, 0x50); + if (sc->mac_ver == 0x5592) { + run_bbp_write(sc, 79, 0x1c); + run_bbp_write(sc, 80, 0x0e); + run_bbp_write(sc, 81, 0x3a); + run_bbp_write(sc, 82, 0x62); + + run_bbp_write(sc, 195, 0x80); + run_bbp_write(sc, 196, 0xe0); + run_bbp_write(sc, 195, 0x81); + run_bbp_write(sc, 196, 0x1f); + run_bbp_write(sc, 195, 0x82); + run_bbp_write(sc, 196, 0x38); + run_bbp_write(sc, 195, 0x83); + run_bbp_write(sc, 196, 0x32); + run_bbp_write(sc, 195, 0x85); + run_bbp_write(sc, 196, 0x28); + run_bbp_write(sc, 195, 0x86); + run_bbp_write(sc, 196, 0x19); + } else if (sc->mac_ver >= 0x5390) + run_bbp_write(sc, 75, 0x50); + else { + run_bbp_write(sc, 82, 0x84); + run_bbp_write(sc, 75, 0x50); + } } } else { - if (sc->mac_ver == 0x3572) + if (sc->mac_ver == 0x5592) { + run_bbp_write(sc, 79, 0x18); + run_bbp_write(sc, 80, 0x08); + run_bbp_write(sc, 81, 0x38); + run_bbp_write(sc, 82, 0x92); + + run_bbp_write(sc, 195, 0x80); + run_bbp_write(sc, 196, 0xf0); + run_bbp_write(sc, 195, 0x81); + run_bbp_write(sc, 196, 0x1e); + run_bbp_write(sc, 195, 0x82); + run_bbp_write(sc, 196, 0x28); + run_bbp_write(sc, 195, 0x83); + run_bbp_write(sc, 196, 0x20); + run_bbp_write(sc, 195, 0x85); + run_bbp_write(sc, 196, 0x7f); + run_bbp_write(sc, 195, 0x86); + run_bbp_write(sc, 196, 0x7f); + } else if (sc->mac_ver == 0x3572) run_bbp_write(sc, 82, 0x94); else run_bbp_write(sc, 82, 0xf2); @@ -3559,6 +3714,11 @@ run_select_chan_group(struct run_softc * } else run_write(sc, RT2860_TX_PIN_CFG, tmp); + if (sc->mac_ver == 0x5592) { + run_bbp_write(sc, 195, 0x8d); + run_bbp_write(sc, 196, 0x1a); + } + /* set initial AGC value */ if (group == 0) { /* 2GHz band */ if (sc->mac_ver >= 0x3070) @@ -3566,7 +3726,9 @@ run_select_chan_group(struct run_softc * else agc = 0x2e + sc->lna[0]; } else { /* 5GHz band */ - if (sc->mac_ver == 0x3572) + if (sc->mac_ver == 0x5592) + agc = 0x24 + sc->lna[group] * 2; + else if (sc->mac_ver == 0x3572) agc = 0x22 + (sc->lna[group] * 5) / 3; else agc = 0x32 + (sc->lna[group] * 5) / 3; @@ -3575,7 +3737,7 @@ run_select_chan_group(struct run_softc * } static void -run_rt2870_set_chan(struct run_softc *sc, uint32_t chan) +run_rt2870_set_chan(struct run_softc *sc, u_int chan) { const struct rfprog *rfprog = rt2860_rf2850; uint32_t r2, r3, r4; @@ -3587,58 +3749,71 @@ run_rt2870_set_chan(struct run_softc *sc r2 = rfprog[i].r2; if (sc->ntxchains == 1) - r2 |= 1 << 12; /* 1T: disable Tx chain 2 */ + r2 |= 1 << 14; /* 1T: disable Tx chain 2 */ if (sc->nrxchains == 1) - r2 |= 1 << 15 | 1 << 4; /* 1R: disable Rx chains 2 & 3 */ + r2 |= 1 << 17 | 1 << 6; /* 1R: disable Rx chains 2 & 3 */ else if (sc->nrxchains == 2) - r2 |= 1 << 4; /* 2R: disable Rx chain 3 */ + r2 |= 1 << 6; /* 2R: disable Rx chain 3 */ /* use Tx power values from EEPROM */ txpow1 = sc->txpow1[i]; txpow2 = sc->txpow2[i]; + + /* Initialize RF R3 and R4. */ + r3 = rfprog[i].r3 & 0xffffc1ff; + r4 = (rfprog[i].r4 & ~(0x001f87c0)) | (sc->freq << 15); if (chan > 14) { - if (txpow1 >= 0) - txpow1 = txpow1 << 1 | 1; - else - txpow1 = (7 + txpow1) << 1; - if (txpow2 >= 0) - txpow2 = txpow2 << 1 | 1; - else - txpow2 = (7 + txpow2) << 1; + if (txpow1 >= 0) { + txpow1 = (txpow1 > 0xf) ? (0xf) : (txpow1); + r3 |= (txpow1 << 10) | (1 << 9); + } else { + txpow1 += 7; + + /* txpow1 is not possible larger than 15. */ + r3 |= (txpow1 << 10); + } + if (txpow2 >= 0) { + txpow2 = (txpow2 > 0xf) ? (0xf) : (txpow2); + r4 |= (txpow2 << 7) | (1 << 6); + } else { + txpow2 += 7; + r4 |= (txpow2 << 7); + } + } else { + /* Set Tx0 power. */ + r3 |= (txpow1 << 9); + + /* Set frequency offset and Tx1 power. */ + r4 |= (txpow2 << 6); *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"