From owner-svn-src-head@FreeBSD.ORG Fri Dec 6 15:26:40 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 853683E8; Fri, 6 Dec 2013 15:26:40 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (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 65A0A16B6; Fri, 6 Dec 2013 15:26:40 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rB6FQe0J011505; Fri, 6 Dec 2013 15:26:40 GMT (envelope-from kevlo@svn.freebsd.org) Received: (from kevlo@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id rB6FQdxZ011500; Fri, 6 Dec 2013 15:26:39 GMT (envelope-from kevlo@svn.freebsd.org) Message-Id: <201312061526.rB6FQdxZ011500@svn.freebsd.org> From: Kevin Lo Date: Fri, 6 Dec 2013 15:26:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r259032 - in head: share/man/man4 sys/dev/usb sys/dev/usb/wlan X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Dec 2013 15:26:40 -0000 Author: kevlo Date: Fri Dec 6 15:26:39 2013 New Revision: 259032 URL: http://svnweb.freebsd.org/changeset/base/259032 Log: Add support for the MediaTek/Ralink RT5572 chipset. Committed over the TP-LINK TL-WDN3200 (RT5572) on amd64 with WPA. While here, add my copyright. Modified: head/share/man/man4/run.4 head/sys/dev/usb/usbdevs head/sys/dev/usb/wlan/if_run.c head/sys/dev/usb/wlan/if_runreg.h head/sys/dev/usb/wlan/if_runvar.h Modified: head/share/man/man4/run.4 ============================================================================== --- head/share/man/man4/run.4 Fri Dec 6 15:17:28 2013 (r259031) +++ head/share/man/man4/run.4 Fri Dec 6 15:26:39 2013 (r259032) @@ -133,6 +133,7 @@ driver supports the following wireless a .It Corega CG-WLUSB300GNM .It D-Link DWA-130 rev B1 .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 @@ -159,6 +160,7 @@ 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 Modified: head/sys/dev/usb/usbdevs ============================================================================== --- head/sys/dev/usb/usbdevs Fri Dec 6 15:17:28 2013 (r259031) +++ head/sys/dev/usb/usbdevs Fri Dec 6 15:26:39 2013 (r259032) @@ -1556,6 +1556,7 @@ product DLINK DUBE100B1 0x3c05 DUB-E100 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 @@ -3606,6 +3607,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: head/sys/dev/usb/wlan/if_run.c ============================================================================== --- head/sys/dev/usb/wlan/if_run.c Fri Dec 6 15:17:28 2013 (r259031) +++ head/sys/dev/usb/wlan/if_run.c Fri Dec 6 15:26:39 2013 (r259032) @@ -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 @@ -173,6 +174,7 @@ static const STRUCT_USB_HOST_ID run_devs 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), @@ -257,6 +259,7 @@ static const STRUCT_USB_HOST_ID run_devs 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), @@ -395,6 +398,7 @@ static void run_rt2870_set_chan(struct r 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 *); @@ -446,6 +450,23 @@ static const struct { 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 { @@ -461,6 +482,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; @@ -472,6 +502,21 @@ static const struct { 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] = { @@ -666,7 +711,7 @@ run_attach(device_t self) 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 == RT3070_RF_3052 || sc->rf_rev == RT5592_RF_5592) setbit(&bands, IEEE80211_MODE_11A); ieee80211_init_channels(ic, NULL, &bands); @@ -1456,6 +1501,7 @@ run_get_rf(uint16_t 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"; } @@ -1538,7 +1584,7 @@ run_read_eeprom(struct run_softc *sc) sc->leds, sc->led[0], sc->led[1], sc->led[2]); /* read RF information */ - if (sc->mac_ver >= 0x5390) + if (sc->mac_ver == 0x5390 || sc->mac_ver ==0x5392) run_srom_read(sc, 0x00, &val); else run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); @@ -1562,7 +1608,7 @@ run_read_eeprom(struct run_softc *sc) sc->nrxchains = 2; } } else { - if (sc->mac_ver >= 0x5390) { + if (sc->mac_ver == 0x5390 || sc->mac_ver ==0x5392) { sc->rf_rev = val; run_srom_read(sc, RT2860_EEPROM_ANTENNA, &val); } else @@ -1631,11 +1677,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]); @@ -2517,12 +2565,15 @@ run_rx_frame(struct run_softc *sc, struc struct rt2870_rxd *rxd; struct rt2860_rxwi *rxwi; uint32_t flags; - uint16_t len; + 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++; @@ -2540,8 +2591,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 *); @@ -2561,7 +2612,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"); @@ -2629,8 +2681,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)) { @@ -2638,8 +2695,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; } @@ -2813,8 +2870,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); @@ -2826,7 +2885,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; @@ -2841,9 +2901,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); @@ -2953,7 +3012,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; @@ -2961,7 +3020,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; @@ -3104,12 +3165,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; @@ -3168,9 +3229,8 @@ 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_txwi)), - rt2860_rates[ridx].rate, qid); + m->m_pkthdr.len + (int)(sizeof(struct rt2870_txd) + + sizeof(struct rt2870_txwi)), rt2860_rates[ridx].rate, qid); return (0); } @@ -3576,7 +3636,25 @@ run_select_chan_group(struct run_softc * run_bbp_write(sc, 75, 0x46); } } else { - if (sc->mac_ver >= 0x5390) + 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); @@ -3584,7 +3662,25 @@ run_select_chan_group(struct run_softc * } } } 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); @@ -3619,6 +3715,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) @@ -3626,7 +3727,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; @@ -4031,6 +4134,143 @@ run_rt5390_set_chan(struct run_softc *sc } static void +run_rt5592_set_chan(struct run_softc *sc, u_int chan) +{ + const struct rt5592_freqs *freqs; + uint32_t tmp; + uint8_t reg, rf, txpow_bound; + int8_t txpow1, txpow2; + int i; + + run_read(sc, RT5592_DEBUG_INDEX, &tmp); + freqs = (tmp & RT5592_SEL_XTAL) ? + rt5592_freqs_40mhz : rt5592_freqs_20mhz; + + /* find the settings for this channel (we know it exists) */ + for (i = 0; rt2860_rf2850[i].chan != chan; i++, freqs++); + + /* use Tx power values from EEPROM */ + txpow1 = sc->txpow1[i]; + txpow2 = sc->txpow2[i]; + + run_read(sc, RT3070_LDO_CFG0, &tmp); + tmp &= ~0x1c000000; + if (chan > 14) + tmp |= 0x14000000; + run_write(sc, RT3070_LDO_CFG0, tmp); + + /* N setting. */ + run_rt3070_rf_write(sc, 8, freqs->n & 0xff); + run_rt3070_rf_read(sc, 9, &rf); + rf &= ~(1 << 4); + rf |= ((freqs->n & 0x0100) >> 8) << 4; + run_rt3070_rf_write(sc, 9, rf); + + /* K setting. */ + run_rt3070_rf_read(sc, 9, &rf); + rf &= ~0x0f; + rf |= (freqs->k & 0x0f); + run_rt3070_rf_write(sc, 9, rf); + + /* Mode setting. */ + run_rt3070_rf_read(sc, 11, &rf); + rf &= ~0x0c; + rf |= ((freqs->m - 0x8) & 0x3) << 2; + run_rt3070_rf_write(sc, 11, rf); + run_rt3070_rf_read(sc, 9, &rf); + rf &= ~(1 << 7); + rf |= (((freqs->m - 0x8) & 0x4) >> 2) << 7; + run_rt3070_rf_write(sc, 9, rf); + + /* R setting. */ + run_rt3070_rf_read(sc, 11, &rf); + rf &= ~0x03; + rf |= (freqs->r - 0x1); + run_rt3070_rf_write(sc, 11, rf); + + if (chan <= 14) { + /* Initialize RF registers for 2GHZ. */ + for (i = 0; i < nitems(rt5592_2ghz_def_rf); i++) { + run_rt3070_rf_write(sc, rt5592_2ghz_def_rf[i].reg, + rt5592_2ghz_def_rf[i].val); + } + + rf = (chan <= 10) ? 0x07 : 0x06; + run_rt3070_rf_write(sc, 23, rf); + run_rt3070_rf_write(sc, 59, rf); + + run_rt3070_rf_write(sc, 55, 0x43); + + /* + * RF R49/R50 Tx power ALC code. + * G-band bit<7:6>=1:0, bit<5:0> range from 0x0 ~ 0x27. + */ + reg = 2; + txpow_bound = 0x27; + } else { + /* Initialize RF registers for 5GHZ. */ + for (i = 0; i < nitems(rt5592_5ghz_def_rf); i++) { + run_rt3070_rf_write(sc, rt5592_5ghz_def_rf[i].reg, + rt5592_5ghz_def_rf[i].val); + } + for (i = 0; i < nitems(rt5592_chan_5ghz); i++) { + if (chan >= rt5592_chan_5ghz[i].firstchan && + chan <= rt5592_chan_5ghz[i].lastchan) { + run_rt3070_rf_write(sc, rt5592_chan_5ghz[i].reg, + rt5592_chan_5ghz[i].val); + } + } + + /* + * RF R49/R50 Tx power ALC code. + * A-band bit<7:6>=1:1, bit<5:0> range from 0x0 ~ 0x2b. + */ + reg = 3; + txpow_bound = 0x2b; + } + + /* RF R49 ch0 Tx power ALC code. */ + run_rt3070_rf_read(sc, 49, &rf); + rf &= ~0xc0; + rf |= (reg << 6); + rf = (rf & ~0x3f) | (txpow1 & 0x3f); + if ((rf & 0x3f) > txpow_bound) + rf = (rf & ~0x3f) | txpow_bound; + run_rt3070_rf_write(sc, 49, rf); + + /* RF R50 ch1 Tx power ALC code. */ + run_rt3070_rf_read(sc, 50, &rf); + rf &= ~(1 << 7 | 1 << 6); + rf |= (reg << 6); + rf = (rf & ~0x3f) | (txpow2 & 0x3f); + if ((rf & 0x3f) > txpow_bound) + rf = (rf & ~0x3f) | txpow_bound; + run_rt3070_rf_write(sc, 50, rf); + + /* Enable RF_BLOCK, PLL_PD, RX0_PD, and TX0_PD. */ + run_rt3070_rf_read(sc, 1, &rf); + rf |= (RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD); + if (sc->ntxchains > 1) + rf |= RT3070_TX1_PD; + if (sc->nrxchains > 1) + rf |= RT3070_RX1_PD; + run_rt3070_rf_write(sc, 1, rf); + + run_rt3070_rf_write(sc, 6, 0xe4); + + run_rt3070_rf_write(sc, 30, 0x10); + run_rt3070_rf_write(sc, 31, 0x80); + run_rt3070_rf_write(sc, 32, 0x80); + + run_adjust_freq_offset(sc); + + /* Enable VCO calibration. */ + run_rt3070_rf_read(sc, 3, &rf); + rf |= RT5390_VCOCAL; + run_rt3070_rf_write(sc, 3, rf); +} + +static void run_set_rx_antenna(struct run_softc *sc, int aux) { uint32_t tmp; @@ -4067,7 +4307,9 @@ run_set_chan(struct run_softc *sc, struc if (chan == 0 || chan == IEEE80211_CHAN_ANY) return (EINVAL); - if (sc->mac_ver >= 0x5390) + if (sc->mac_ver == 0x5592) + run_rt5592_set_chan(sc, chan); + else if (sc->mac_ver >= 0x5390) run_rt5390_set_chan(sc, chan); else if (sc->mac_ver == 0x3572) run_rt3572_set_chan(sc, chan); @@ -4192,6 +4434,7 @@ run_update_beacon_cb(void *arg) struct run_softc *sc = ic->ic_ifp->if_softc; struct rt2860_txwi txwi; struct mbuf *m; + uint16_t txwisize; uint8_t ridx; if (vap->iv_bss->ni_chan == IEEE80211_CHAN_ANYC) @@ -4211,25 +4454,26 @@ run_update_beacon_cb(void *arg) } m = rvp->beacon_mbuf; - memset(&txwi, 0, sizeof txwi); + memset(&txwi, 0, sizeof(txwi)); txwi.wcid = 0xff; txwi.len = htole16(m->m_pkthdr.len); + /* send beacons at the lowest available rate */ ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ? RT2860_RIDX_OFDM6 : RT2860_RIDX_CCK1; txwi.phy = htole16(rt2860_rates[ridx].mcs); if (rt2860_rates[ridx].phy == IEEE80211_T_OFDM) - txwi.phy |= htole16(RT2860_PHY_OFDM); + txwi.phy |= htole16(RT2860_PHY_OFDM); txwi.txop = RT2860_TX_TXOP_HT; txwi.flags = RT2860_TX_TS; txwi.xflags = RT2860_TX_NSEQ; - run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id), - (uint8_t *)&txwi, sizeof txwi); - run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id) + sizeof txwi, - mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1); /* roundup len */ - - return; + txwisize = (sc->mac_ver == 0x5592) ? + sizeof(txwi) + sizeof(uint32_t) : sizeof(txwi); + run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id), (uint8_t *)&txwi, + txwisize); + run_write_region_1(sc, RT2860_BCN_BASE(rvp->rvp_id) + txwisize, + mtod(m, uint8_t *), (m->m_pkthdr.len + 1) & ~1); } static void @@ -4526,15 +4770,31 @@ static void run_rt5390_bbp_init(struct run_softc *sc) { int i; - uint8_t bbp4; + uint8_t bbp; + + /* Apply maximum likelihood detection for 2 stream case. */ + run_bbp_read(sc, 105, &bbp); + if (sc->nrxchains > 1) + run_bbp_write(sc, 105, bbp | RT5390_MLD); /* Avoid data lost and CRC error. */ - run_bbp_read(sc, 4, &bbp4); + run_bbp_read(sc, 4, &bbp); run_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL); - for (i = 0; i < nitems(rt5390_def_bbp); i++) { - run_bbp_write(sc, rt5390_def_bbp[i].reg, - rt5390_def_bbp[i].val); + if (sc->mac_ver == 0x5592) { + for (i = 0; i < nitems(rt5592_def_bbp); i++) { + run_bbp_write(sc, rt5592_def_bbp[i].reg, + rt5592_def_bbp[i].val); + } + for (i = 0; i < nitems(rt5592_bbp_r196); i++) { + run_bbp_write(sc, 195, i + 0x80); + run_bbp_write(sc, 196, rt5592_bbp_r196[i]); + } + } else { + for (i = 0; i < nitems(rt5390_def_bbp); i++) { + run_bbp_write(sc, rt5390_def_bbp[i].reg, + rt5390_def_bbp[i].val); + } } if (sc->mac_ver == 0x5392) { run_bbp_write(sc, 88, 0x90); @@ -4546,9 +4806,22 @@ run_rt5390_bbp_init(struct run_softc *sc run_bbp_write(sc, 148, 0x84); } + run_bbp_read(sc, 152, &bbp); + run_bbp_write(sc, 152, bbp | 0x80); + + /* Fix BBP254 for RT5592C. */ + if (sc->mac_ver == 0x5592 && sc->mac_rev >= 0x0221) { + run_bbp_read(sc, 254, &bbp); + run_bbp_write(sc, 254, bbp | 0x80); + } + /* Disable hardware antenna diversity. */ if (sc->mac_ver == 0x5390) run_bbp_write(sc, 154, 0); + + /* Initialize Rx CCK/OFDM frequency offset report. */ + run_bbp_write(sc, 142, 1); + run_bbp_write(sc, 143, 57); } static int @@ -4581,7 +4854,7 @@ run_bbp_init(struct run_softc *sc) if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) run_bbp_write(sc, 84, 0x19); - if (sc->mac_ver >= 0x3070) { + if (sc->mac_ver >= 0x3070 && sc->mac_ver != 0x5592) { run_bbp_write(sc, 79, 0x13); run_bbp_write(sc, 80, 0x05); run_bbp_write(sc, 81, 0x33); @@ -4755,7 +5028,14 @@ run_rt5390_rf_init(struct run_softc *sc) } /* Initialize RF registers to default value. */ - if (sc->mac_ver == 0x5392) { + if (sc->mac_ver == 0x5592) { + for (i = 0; i < nitems(rt5592_def_rf); i++) { + run_rt3070_rf_write(sc, rt5592_def_rf[i].reg, + rt5592_def_rf[i].val); + } + /* Initialize RF frequency offset. */ + run_adjust_freq_offset(sc); + } else if (sc->mac_ver == 0x5392) { for (i = 0; i < nitems(rt5392_def_rf); i++) { run_rt3070_rf_write(sc, rt5392_def_rf[i].reg, rt5392_def_rf[i].val); @@ -4784,7 +5064,7 @@ run_rt5390_rf_init(struct run_softc *sc) } sc->rf24_20mhz = 0x1f; /* default value */ - sc->rf24_40mhz = 0x2f; /* default value */ + sc->rf24_40mhz = (sc->mac_ver == 0x5592) ? 0 : 0x2f; if (sc->mac_rev < 0x0211) run_rt3070_rf_write(sc, 27, 0x3); @@ -4869,9 +5149,11 @@ run_rt3070_rf_setup(struct run_softc *sc /* Enable DC filter. */ run_bbp_write(sc, 103, 0xc0); - /* Improve power consumption. */ - run_bbp_read(sc, 31, &bbp); - run_bbp_write(sc, 31, bbp & ~0x03); + if (sc->mac_ver != 0x5592) { + /* Improve power consumption. */ + run_bbp_read(sc, 31, &bbp); + run_bbp_write(sc, 31, bbp & ~0x03); + } } run_bbp_read(sc, 138, &bbp); @@ -4895,12 +5177,14 @@ run_rt3070_rf_setup(struct run_softc *sc rf = (rf & ~0x18) | 0x10; run_rt3070_rf_write(sc, 30, rf); - run_write(sc, RT2860_TX_SW_CFG1, 0); - if (sc->mac_rev < 0x0211) { - run_write(sc, RT2860_TX_SW_CFG2, - sc->patch_dac ? 0x2c : 0x0f); - } else - run_write(sc, RT2860_TX_SW_CFG2, 0); + if (sc->mac_ver != 0x5592) { + run_write(sc, RT2860_TX_SW_CFG1, 0); + if (sc->mac_rev < 0x0211) { + run_write(sc, RT2860_TX_SW_CFG2, + sc->patch_dac ? 0x2c : 0x0f); + } else + run_write(sc, RT2860_TX_SW_CFG2, 0); + } } else if (sc->mac_ver == 0x3572) { /* enable DC filter */ @@ -5119,8 +5403,13 @@ run_init_locked(struct run_softc *sc) 4 << RT2860_DLY_PAPE_EN_SHIFT | 4); if (sc->mac_ver >= 0x5392) { run_write(sc, RT2860_MAX_LEN_CFG, 0x00002fff); - run_write(sc, RT2860_HT_FBK_CFG1, 0xedcb4980); - run_write(sc, RT2860_LG_FBK_CFG0, 0xedcba322); + if (sc->mac_ver == 0x5592) { + run_write(sc, RT2860_HT_FBK_CFG1, 0xedcba980); + run_write(sc, RT2860_TXOP_HLDR_ET, 0x00000082); + } else { + run_write(sc, RT2860_HT_FBK_CFG1, 0xedcb4980); + run_write(sc, RT2860_LG_FBK_CFG0, 0xedcba322); + } } } else if (sc->mac_ver >= 0x3070) { /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ Modified: head/sys/dev/usb/wlan/if_runreg.h ============================================================================== --- head/sys/dev/usb/wlan/if_runreg.h Fri Dec 6 15:17:28 2013 (r259031) +++ head/sys/dev/usb/wlan/if_runreg.h Fri Dec 6 15:26:39 2013 (r259032) @@ -22,13 +22,6 @@ #ifndef _IF_RUNREG_H_ #define _IF_RUNREG_H_ -/* PCI registers */ -#define RT2860_PCI_CFG 0x0000 -#define RT2860_PCI_EECTRL 0x0004 -#define RT2860_PCI_MCUCTRL 0x0008 -#define RT2860_PCI_SYSCTRL 0x000c -#define RT2860_PCIE_JTAG 0x0010 - #define RT2860_CONFIG_NO 1 #define RT2860_IFACE_INDEX 0 @@ -85,6 +78,9 @@ #define RT3070_LDO_CFG0 0x05d4 #define RT3070_GPIO_SWITCH 0x05dc +/* RT5592 registers */ +#define RT5592_DEBUG_INDEX 0x05e8 + /* MAC registers */ #define RT2860_ASIC_VER_ID 0x1000 #define RT2860_MAC_SYS_CTRL 0x1004 @@ -387,6 +383,9 @@ #define RT3070_EFSROM_MODE_MASK 0x000000c0 #define RT3070_EFUSE_AOUT_MASK 0x0000003f +/* possible flag for register DEBUG_INDEX */ +#define RT5592_SEL_XTAL (1U << 31) + /* possible flags for register MAC_SYS_CTRL */ #define RT2860_RX_TS_EN (1 << 7) #define RT2860_WLAN_HALT_EN (1 << 6) @@ -847,13 +846,6 @@ struct rt2860_rxwi { uint16_t reserved2; } __packed; - -/* first DMA segment contains TXWI + 802.11 header + 32-bit padding */ -#define RT2860_TXWI_DMASZ \ - (sizeof (struct rt2860_txwi) + \ - sizeof (struct ieee80211_htframe) + \ - sizeof (uint16_t)) - #define RT2860_RF_2820 0x0001 /* 2T3R */ #define RT2860_RF_2850 0x0002 /* dual-band 2T3R */ #define RT2860_RF_2720 0x0003 /* 1T2R */ @@ -863,6 +855,7 @@ struct rt2860_rxwi { #define RT3070_RF_3021 0x0007 /* 1T2R */ #define RT3070_RF_3022 0x0008 /* 2T2R */ #define RT3070_RF_3052 0x0009 /* dual-band 2T2R */ +#define RT5592_RF_5592 0x000f /* dual-band 2T2R */ #define RT5390_RF_5370 0x5370 /* 1T1R */ #define RT5390_RF_5372 0x5372 /* 2T2R */ @@ -1029,6 +1022,38 @@ static const struct rt2860_rate { { 106, 0x03 }, \ { 128, 0x12 } +#define RT5592_DEF_BBP \ + { 20, 0x06 }, \ + { 31, 0x08 }, \ + { 65, 0x2c }, \ + { 66, 0x38 }, \ + { 68, 0xdd }, \ + { 69, 0x1a }, \ + { 70, 0x05 }, \ + { 73, 0x13 }, \ + { 74, 0x0f }, \ + { 75, 0x4f }, \ + { 76, 0x28 }, \ + { 77, 0x59 }, \ + { 81, 0x37 }, \ + { 82, 0x62 }, \ + { 83, 0x6a }, \ + { 84, 0x9a }, \ + { 86, 0x38 }, \ + { 88, 0x90 }, \ + { 91, 0x04 }, \ + { 92, 0x02 }, \ + { 95, 0x9a }, \ + { 98, 0x12 }, \ + { 103, 0xc0 }, \ + { 104, 0x92 }, \ + { 105, 0x3c }, \ + { 106, 0x35 }, \ + { 128, 0x12 }, \ + { 134, 0xd0 }, \ + { 135, 0xf6 }, \ + { 137, 0x0f } + /* * Default settings for RF registers; values derived from the reference driver. */ @@ -1149,6 +1174,116 @@ static const struct rt2860_rate { { 0x61, 0, 7 }, \ { 0x61, 0, 9 } +#define RT5592_RF5592_20MHZ \ + { 0x1e2, 4, 10, 3 }, \ + { 0x1e3, 4, 10, 3 }, \ + { 0x1e4, 4, 10, 3 }, \ + { 0x1e5, 4, 10, 3 }, \ + { 0x1e6, 4, 10, 3 }, \ + { 0x1e7, 4, 10, 3 }, \ + { 0x1e8, 4, 10, 3 }, \ + { 0x1e9, 4, 10, 3 }, \ + { 0x1ea, 4, 10, 3 }, \ + { 0x1eb, 4, 10, 3 }, \ + { 0x1ec, 4, 10, 3 }, \ + { 0x1ed, 4, 10, 3 }, \ + { 0x1ee, 4, 10, 3 }, \ + { 0x1f0, 8, 10, 3 }, \ + { 0xac, 8, 12, 1 }, \ + { 0xad, 0, 12, 1 }, \ + { 0xad, 4, 12, 1 }, \ + { 0xae, 0, 12, 1 }, \ + { 0xae, 4, 12, 1 }, \ + { 0xae, 8, 12, 1 }, \ + { 0xaf, 4, 12, 1 }, \ + { 0xaf, 8, 12, 1 }, \ + { 0xb0, 0, 12, 1 }, \ + { 0xb0, 8, 12, 1 }, \ + { 0xb1, 0, 12, 1 }, \ + { 0xb1, 4, 12, 1 }, \ + { 0xb7, 4, 12, 1 }, \ + { 0xb7, 8, 12, 1 }, \ + { 0xb8, 0, 12, 1 }, \ + { 0xb8, 8, 12, 1 }, \ + { 0xb9, 0, 12, 1 }, \ + { 0xb9, 4, 12, 1 }, \ + { 0xba, 0, 12, 1 }, \ + { 0xba, 4, 12, 1 }, \ + { 0xba, 8, 12, 1 }, \ + { 0xbb, 4, 12, 1 }, \ + { 0xbb, 8, 12, 1 }, \ + { 0xbc, 0, 12, 1 }, \ + { 0xbc, 8, 12, 1 }, \ + { 0xbd, 0, 12, 1 }, \ + { 0xbd, 4, 12, 1 }, \ + { 0xbe, 0, 12, 1 }, \ + { 0xbf, 6, 12, 1 }, \ + { 0xbf, 10, 12, 1 }, \ + { 0xc0, 2, 12, 1 }, \ + { 0xc0, 10, 12, 1 }, \ + { 0xc1, 2, 12, 1 }, \ + { 0xc1, 6, 12, 1 }, \ + { 0xc2, 2, 12, 1 }, \ + { 0xa4, 0, 12, 1 }, \ + { 0xa4, 4, 12, 1 }, \ + { 0xa5, 8, 12, 1 }, \ + { 0xa6, 0, 12, 1 } + +#define RT5592_RF5592_40MHZ \ + { 0xf1, 2, 10, 3 }, \ + { 0xf1, 7, 10, 3 }, \ + { 0xf2, 2, 10, 3 }, \ + { 0xf2, 7, 10, 3 }, \ + { 0xf3, 2, 10, 3 }, \ + { 0xf3, 7, 10, 3 }, \ + { 0xf4, 2, 10, 3 }, \ + { 0xf4, 7, 10, 3 }, \ + { 0xf5, 2, 10, 3 }, \ + { 0xf5, 7, 10, 3 }, \ + { 0xf6, 2, 10, 3 }, \ + { 0xf6, 7, 10, 3 }, \ + { 0xf7, 2, 10, 3 }, \ + { 0xf8, 4, 10, 3 }, \ + { 0x56, 4, 12, 1 }, \ + { 0x56, 6, 12, 1 }, \ + { 0x56, 8, 12, 1 }, \ + { 0x57, 0, 12, 1 }, \ + { 0x57, 2, 12, 1 }, \ + { 0x57, 4, 12, 1 }, \ + { 0x57, 8, 12, 1 }, \ + { 0x57, 10, 12, 1 }, \ + { 0x58, 0, 12, 1 }, \ + { 0x58, 4, 12, 1 }, \ + { 0x58, 6, 12, 1 }, \ + { 0x58, 8, 12, 1 }, \ + { 0x5b, 8, 12, 1 }, \ + { 0x5b, 10, 12, 1 }, \ + { 0x5c, 0, 12, 1 }, \ + { 0x5c, 4, 12, 1 }, \ + { 0x5c, 6, 12, 1 }, \ + { 0x5c, 8, 12, 1 }, \ + { 0x5d, 0, 12, 1 }, \ + { 0x5d, 2, 12, 1 }, \ + { 0x5d, 4, 12, 1 }, \ + { 0x5d, 8, 12, 1 }, \ + { 0x5d, 10, 12, 1 }, \ + { 0x5e, 0, 12, 1 }, \ + { 0x5e, 4, 12, 1 }, \ + { 0x5e, 6, 12, 1 }, \ + { 0x5e, 8, 12, 1 }, \ + { 0x5f, 0, 12, 1 }, \ + { 0x5f, 9, 12, 1 }, \ + { 0x5f, 11, 12, 1 }, \ + { 0x60, 1, 12, 1 }, \ + { 0x60, 5, 12, 1 }, \ + { 0x60, 7, 12, 1 }, \ + { 0x60, 9, 12, 1 }, \ + { 0x61, 1, 12, 1 }, \ + { 0x52, 0, 12, 1 }, \ + { 0x52, 4, 12, 1 }, \ + { 0x52, 8, 12, 1 }, \ + { 0x53, 0, 12, 1 } + #define RT3070_DEF_RF \ { 4, 0x40 }, \ { 5, 0x03 }, \ @@ -1322,6 +1457,128 @@ static const struct rt2860_rate { { 62, 0x39 }, \ { 63, 0x07 } +#define RT5592_DEF_RF \ + { 1, 0x3f }, \ + { 3, 0x08 }, \ + { 5, 0x10 }, \ + { 6, 0xe4 }, \ + { 7, 0x00 }, \ + { 14, 0x00 }, \ + { 15, 0x00 }, \ + { 16, 0x00 }, \ + { 18, 0x03 }, \ + { 19, 0x4d }, \ + { 20, 0x10 }, \ + { 21, 0x8d }, \ + { 26, 0x82 }, \ + { 28, 0x00 }, \ + { 29, 0x10 }, \ + { 33, 0xc0 }, \ + { 34, 0x07 }, \ + { 35, 0x12 }, \ + { 47, 0x0c }, \ + { 53, 0x22 }, \ + { 63, 0x07 } + +#define RT5592_2GHZ_DEF_RF \ + { 10, 0x90 }, \ + { 11, 0x4a }, \ + { 12, 0x52 }, \ + { 13, 0x42 }, \ + { 22, 0x40 }, \ + { 24, 0x4a }, \ + { 25, 0x80 }, \ *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***