From: kevlo Date: Fri, 16 Jun 2017 14:57:51 +0000 (+0000) Subject: - Fix incorrect values in the computation of transmit power for the X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=34a2cadeaf3cc12eee053c33454e9eadb946f8f3;p=openbsd - Fix incorrect values in the computation of transmit power for the rtl8188eu chipset. - Small code refactoring: - replace hardcoded rate indexes with their name, like athn(4). - replace fields offsets with the structure; from FreeBSD r294198. - be compliant with definitions of the efuse in vendor hal_pg.h and rename struct r92c_rom member names: s/channel_plan/reserved5/, s/xtal_calib/channel_plan. - no need to disable HWPDN twice in urtwn_r88e_power_on(). Tested by stsp@ and myself with RTL8188CUS, RTL8192CU, RTL8188EU, and RTL8188CE devices. ok stsp@ --- diff --git a/sys/dev/ic/r92creg.h b/sys/dev/ic/r92creg.h index eaa1dc60bb7..7d8d0446e23 100644 --- a/sys/dev/ic/r92creg.h +++ b/sys/dev/ic/r92creg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: r92creg.h,v 1.9 2017/05/19 18:15:15 stsp Exp $ */ +/* $OpenBSD: r92creg.h,v 1.10 2017/06/16 14:57:51 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -1015,7 +1015,7 @@ struct r92c_rom { uint16_t reserved3; uint8_t usb_phy; uint8_t reserved4[3]; - uint8_t macaddr[6]; + uint8_t macaddr[IEEE80211_ADDR_LEN]; uint8_t string[61]; /* "Realtek" */ uint8_t subcustomer_id; uint8_t cck_tx_pwr[R92C_MAX_CHAINS][3]; @@ -1025,7 +1025,7 @@ struct r92c_rom { uint8_t ofdm_tx_pwr_diff[3]; uint8_t ht40_max_pwr[3]; uint8_t ht20_max_pwr[3]; - uint8_t xtal_calib; + uint8_t channel_plan; uint8_t tssi[R92C_MAX_CHAINS]; uint8_t thermal_meter; uint8_t rf_opt1; @@ -1042,11 +1042,51 @@ struct r92c_rom { uint8_t rf_opt2; uint8_t rf_opt3; uint8_t rf_opt4; - uint8_t channel_plan; + uint8_t reserved5; uint8_t version; uint8_t curstomer_id; } __packed; +struct r88e_tx_pwr { + uint8_t cck_tx_pwr[6]; + uint8_t ht40_tx_pwr[5]; + uint8_t ht20_ofdm_tx_pwr_diff; +#define R88E_ROM_TXPWR_HT20_DIFF_M 0xf0 +#define R88E_ROM_TXPWR_HT20_DIFF_S 4 +#define R88E_ROM_TXPWR_OFDM_DIFF_M 0x0f +#define R88E_ROM_TXPWR_OFDM_DIFF_S 0 + +} __packed; + +/* + * RTL8188EU ROM image. + */ +struct r88e_rom { + uint8_t reserved1[16]; + struct r88e_tx_pwr txpwr; + uint8_t reserved2[156]; + uint8_t channel_plan; + uint8_t xtal; + uint8_t thermal_meter; + uint8_t reserved3[6]; + uint8_t rf_board_opt; + uint8_t rf_feature_opt; + uint8_t rf_bt_opt; + uint8_t version; + uint8_t customer_id; + uint8_t reserved4[3]; + uint8_t rf_ant_opt; + uint8_t reserved5[6]; + uint16_t vid; + uint16_t pid; + uint8_t usb_opt; + uint8_t reserved6[2]; + uint8_t macaddr[IEEE80211_ADDR_LEN]; + uint8_t reserved7[2]; + uint8_t string[33]; /* "Realtek" */ + uint8_t reserved8[256]; +} __packed; + /* Rx PHY descriptor. */ struct r92c_rx_phystat { uint32_t phydw0; @@ -2272,10 +2312,6 @@ struct r92c_txpwr { uint8_t pwr[3][28]; }; -struct r88e_txpwr { - uint8_t pwr[6][28]; -}; - /* * Per RF chain/group/rate Tx gain values. */ @@ -2344,44 +2380,3 @@ static const struct r92c_txpwr rtl8188ru_txagc[] = { } } } }; - -static const struct r88e_txpwr rtl8188eu_txagc[] = { - { { /* Chain 0. */ - { /* Group 0. */ - 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */ - }, - { /* Group 1. */ - 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */ - }, - { /* Group 2. */ - 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */ - }, - { /* Group 3. */ - 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */ - }, - { /* Group 4. */ - 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */ - }, - { /* Group 5. */ - 0x00, 0x00, 0x00, 0x00, /* CCK1~11. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* OFDM6~54. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MCS0~7. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* MCS8~15. */ - } - } } -}; diff --git a/sys/dev/ic/rtwn.c b/sys/dev/ic/rtwn.c index 75baea282dc..bca14ca6921 100644 --- a/sys/dev/ic/rtwn.c +++ b/sys/dev/ic/rtwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtwn.c,v 1.21 2017/05/19 18:15:15 stsp Exp $ */ +/* $OpenBSD: rtwn.c,v 1.22 2017/06/16 14:57:51 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -18,7 +18,7 @@ */ /* - * Driver for Realtek RTL8188CE + * Driver for Realtek 802.11b/g/n chipsets. */ #include "bpfilter.h" @@ -54,7 +54,31 @@ #include #include -#define RTWN_RIDX_COUNT 28 +#define RTWN_RIDX_CCK1 0 +#define RTWN_RIDX_CCK2 1 +#define RTWN_RIDX_CCK11 3 +#define RTWN_RIDX_OFDM6 4 +#define RTWN_RIDX_OFDM54 11 +#define RTWN_RIDX_MCS0 12 +#define RTWN_RIDX_MCS8 (RTWN_RIDX_MCS0 + 8) +#define RTWN_RIDX_MCS15 27 +#define RTWN_RIDX_MAX 27 + +#define RTWN_POWER_CCK1 0 +#define RTWN_POWER_CCK2 1 +#define RTWN_POWER_CCK55 2 +#define RTWN_POWER_CCK11 3 +#define RTWN_POWER_OFDM6 4 +#define RTWN_POWER_OFDM9 5 +#define RTWN_POWER_OFDM12 6 +#define RTWN_POWER_OFDM18 7 +#define RTWN_POWER_OFDM24 8 +#define RTWN_POWER_OFDM36 9 +#define RTWN_POWER_OFDM48 10 +#define RTWN_POWER_OFDM54 11 +#define RTWN_POWER_MCS(mcs) (12 + (mcs)) +#define RTWN_POWER_COUNT 28 + #ifdef RTWN_DEBUG #define DPRINTF(x) do { if (rtwn_debug) printf x; } while (0) @@ -76,10 +100,11 @@ void rtwn_rf_write(struct rtwn_softc *, int, uint8_t, uint32_t); uint32_t rtwn_rf_read(struct rtwn_softc *, int, uint8_t); void rtwn_cam_write(struct rtwn_softc *, uint32_t, uint32_t); uint8_t rtwn_efuse_read_1(struct rtwn_softc *, uint16_t); -void rtwn_efuse_read(struct rtwn_softc *); +void rtwn_efuse_read(struct rtwn_softc *, uint8_t *, size_t); void rtwn_efuse_switch_power(struct rtwn_softc *); -int rtwn_read_chipid(struct rtwn_softc *, uint32_t); -void rtwn_read_rom(struct rtwn_softc *); +int rtwn_read_chipid(struct rtwn_softc *); +void rtwn_read_rom(void *); +void rtwn_r92c_read_rom(struct rtwn_softc *); void rtwn_r88e_read_rom(struct rtwn_softc *); int rtwn_media_change(struct ifnet *); int rtwn_ra_init(struct rtwn_softc *); @@ -101,7 +126,9 @@ void rtwn_pa_bias_init(struct rtwn_softc *); void rtwn_rxfilter_init(struct rtwn_softc *); void rtwn_edca_init(struct rtwn_softc *); void rtwn_write_txpower(struct rtwn_softc *, int, uint16_t[]); -void rtwn_get_txpower(struct rtwn_softc *, int, +void rtwn_get_txpower(void *, int, struct ieee80211_channel *, + struct ieee80211_channel *, uint16_t[]); +void rtwn_r92c_get_txpower(struct rtwn_softc *, int, struct ieee80211_channel *, struct ieee80211_channel *, uint16_t[]); void rtwn_r88e_get_txpower(struct rtwn_softc *, int, @@ -132,8 +159,13 @@ void rtwn_stop(struct ifnet *); #define rtwn_bb_write rtwn_write_4 #define rtwn_bb_read rtwn_read_4 +/* + * Macro to convert 4-bit signed integer to 8-bit signed integer. + */ +#define RTWN_SIGN4TO8(val) (((val) & 0x08) ? (val) | 0xf0 : (val)) + int -rtwn_attach(struct device *pdev, struct rtwn_softc *sc, uint32_t chip_type) +rtwn_attach(struct device *pdev, struct rtwn_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; @@ -143,13 +175,15 @@ rtwn_attach(struct device *pdev, struct rtwn_softc *sc, uint32_t chip_type) task_set(&sc->init_task, rtwn_init_task, sc); - sc->chip = 0; - error = rtwn_read_chipid(sc, chip_type); + error = rtwn_read_chipid(sc); if (error != 0) { printf("%s: unsupported chip\n", sc->sc_pdev->dv_xname); return (ENXIO); } + sc->sc_ops.get_txpower = rtwn_get_txpower; + sc->sc_ops.read_rom = rtwn_read_rom; + /* Determine number of Tx/Rx chains. */ if (sc->chip & RTWN_CHIP_92C) { sc->ntxchains = (sc->chip & RTWN_CHIP_92C_1T2R) ? 1 : 2; @@ -159,10 +193,7 @@ rtwn_attach(struct device *pdev, struct rtwn_softc *sc, uint32_t chip_type) sc->nrxchains = 1; } - if (sc->chip & RTWN_CHIP_88E) - rtwn_r88e_read_rom(sc); - else - rtwn_read_rom(sc); + rtwn_read_rom(sc); if (sc->chip & RTWN_CHIP_PCI) { printf("%s: MAC/BB RTL%s, RF 6052 %dT%dR, address %s\n", @@ -438,24 +469,34 @@ rtwn_efuse_read_1(struct rtwn_softc *sc, uint16_t addr) } void -rtwn_efuse_read(struct rtwn_softc *sc) +rtwn_efuse_read(struct rtwn_softc *sc, uint8_t *rom, size_t size) { - uint8_t *rom = (uint8_t *)&sc->rom; + uint8_t off, msk, tmp; uint16_t addr = 0; uint32_t reg; - uint8_t off, msk; - int i; + int i, len; rtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON); rtwn_efuse_switch_power(sc); - memset(&sc->rom, 0xff, sizeof(sc->rom)); - while (addr < 512) { + memset(rom, 0xff, size); + len = (sc->chip & RTWN_CHIP_88E) ? 256 : 512; + while (addr < len) { reg = rtwn_efuse_read_1(sc, addr); if (reg == 0xff) break; addr++; - off = reg >> 4; + + /* Check for extended header. */ + if ((sc->sc_flags & RTWN_FLAG_EXT_HDR) && + (reg & 0x1f) == 0x0f) { + tmp = (reg & 0xe0) >> 5; + reg = rtwn_efuse_read_1(sc, addr); + if ((reg & 0x0f) != 0x0f) + off = ((reg & 0xf0) >> 1) | tmp; + addr++; + } else + off = reg >> 4; msk = reg & 0xf; for (i = 0; i < 4; i++) { if (msk & (1 << i)) @@ -472,7 +513,7 @@ rtwn_efuse_read(struct rtwn_softc *sc) if (rtwn_debug >= 2) { /* Dump ROM content. */ printf("\n"); - for (i = 0; i < sizeof(sc->rom); i++) + for (i = 0; i < size); i++) printf("%02x:", rom[i]); printf("\n"); } @@ -504,12 +545,12 @@ rtwn_efuse_switch_power(struct rtwn_softc *sc) } int -rtwn_read_chipid(struct rtwn_softc *sc, uint32_t chip_type) +rtwn_read_chipid(struct rtwn_softc *sc) { uint32_t reg; - if (chip_type & RTWN_CHIP_88E) { - sc->chip = chip_type; + if (sc->chip & RTWN_CHIP_88E) { + sc->sc_flags |= RTWN_FLAG_EXT_HDR; return (0); } @@ -518,16 +559,16 @@ rtwn_read_chipid(struct rtwn_softc *sc, uint32_t chip_type) /* Unsupported test chip. */ return (EIO); - if ((chip_type & (RTWN_CHIP_92C | RTWN_CHIP_88C)) != 0) { + if ((sc->chip & (RTWN_CHIP_92C | RTWN_CHIP_88C)) != 0) { if (reg & R92C_SYS_CFG_TYPE_92C) { - sc->chip = RTWN_CHIP_92C; + sc->chip &= ~RTWN_CHIP_88C; /* Check if it is a castrated 8192C. */ if (MS(rtwn_read_4(sc, R92C_HPON_FSM), R92C_HPON_FSM_CHIP_BONDING_ID) == R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R) sc->chip |= RTWN_CHIP_92C_1T2R; } else - sc->chip = RTWN_CHIP_88C; + sc->chip &= ~RTWN_CHIP_92C; if (reg & R92C_SYS_CFG_VENDOR_UMC) { sc->chip |= RTWN_CHIP_UMC; @@ -535,7 +576,6 @@ rtwn_read_chipid(struct rtwn_softc *sc, uint32_t chip_type) sc->chip |= RTWN_CHIP_UMC_A_CUT; } - sc->chip |= (chip_type & (RTWN_CHIP_USB | RTWN_CHIP_PCI)); return (0); } @@ -543,13 +583,25 @@ rtwn_read_chipid(struct rtwn_softc *sc, uint32_t chip_type) } void -rtwn_read_rom(struct rtwn_softc *sc) +rtwn_read_rom(void *cookie) +{ + struct rtwn_softc *sc = cookie; + + if (sc->chip & RTWN_CHIP_88E) + rtwn_r88e_read_rom(sc); + else + rtwn_r92c_read_rom(sc); +} + +void +rtwn_r92c_read_rom(struct rtwn_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - struct r92c_rom *rom = &sc->rom; + struct r92c_rom *rom = &sc->sc_r92c_rom; /* Read full ROM image. */ - rtwn_efuse_read(sc); + rtwn_efuse_read(sc, (uint8_t *)&sc->sc_r92c_rom, + sizeof(sc->sc_r92c_rom)); /* XXX Weird but this is what the vendor driver does. */ sc->pa_setting = rtwn_efuse_read_1(sc, 0x1fa); @@ -568,60 +620,19 @@ void rtwn_r88e_read_rom(struct rtwn_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - uint8_t *rom = sc->r88e_rom; - uint16_t addr = 0; - uint32_t reg; - uint8_t off, msk, tmp; - int i; - - off = 0; - - rtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_ON); - rtwn_efuse_switch_power(sc); + struct r88e_rom *rom = &sc->sc_r88e_rom; /* Read full ROM image. */ - memset(&sc->r88e_rom, 0xff, sizeof(sc->r88e_rom)); - while (addr < 512) { - reg = rtwn_efuse_read_1(sc, addr); - if (reg == 0xff) - break; - addr++; - if ((reg & 0x1f) == 0x0f) { - tmp = (reg & 0xe0) >> 5; - reg = rtwn_efuse_read_1(sc, addr); - if ((reg & 0x0f) != 0x0f) - off = ((reg & 0xf0) >> 1) | tmp; - addr++; - } else - off = reg >> 4; - msk = reg & 0xf; - for (i = 0; i < 4; i++) { - if (msk & (1 << i)) - continue; - rom[off * 8 + i * 2 + 0] = - rtwn_efuse_read_1(sc, addr); - addr++; - rom[off * 8 + i * 2 + 1] = - rtwn_efuse_read_1(sc, addr); - addr++; - } - } + rtwn_efuse_read(sc, (uint8_t *)&sc->sc_r88e_rom, + sizeof(sc->sc_r88e_rom)); - rtwn_write_1(sc, R92C_EFUSE_ACCESS, R92C_EFUSE_ACCESS_OFF); + sc->crystal_cap = rom->xtal; + DPRINTF(("Crystal cap=0x%x\n", sc->crystal_cap)); + + sc->regulatory = MS(rom->rf_board_opt, R92C_ROM_RF1_REGULATORY); + DPRINTF(("regulatory type=%d\n", sc->regulatory)); - addr = 0x10; - for (i = 0; i < 6; i++) - sc->cck_tx_pwr[i] = sc->r88e_rom[addr++]; - for (i = 0; i < 5; i++) - sc->ht40_tx_pwr[i] = sc->r88e_rom[addr++]; - sc->bw20_tx_pwr_diff = (sc->r88e_rom[addr] & 0xf0) >> 4; - if (sc->bw20_tx_pwr_diff & 0x08) - sc->bw20_tx_pwr_diff |= 0xf0; - sc->ofdm_tx_pwr_diff = (sc->r88e_rom[addr] & 0xf); - if (sc->ofdm_tx_pwr_diff & 0x08) - sc->ofdm_tx_pwr_diff |= 0xf0; - sc->regulatory = MS(sc->r88e_rom[0xc1], R92C_ROM_RF1_REGULATORY); - IEEE80211_ADDR_COPY(ic->ic_myaddr, &sc->r88e_rom[0xd7]); + IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr); } int @@ -1763,71 +1774,83 @@ rtwn_edca_init(struct rtwn_softc *sc) void rtwn_write_txpower(struct rtwn_softc *sc, int chain, - uint16_t power[RTWN_RIDX_COUNT]) + uint16_t power[RTWN_POWER_COUNT]) { uint32_t reg; /* Write per-CCK rate Tx power. */ if (chain == 0) { reg = rtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32); - reg = RW(reg, R92C_TXAGC_A_CCK1, power[0]); + reg = RW(reg, R92C_TXAGC_A_CCK1, power[RTWN_POWER_CCK1]); rtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg); reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11); - reg = RW(reg, R92C_TXAGC_A_CCK2, power[1]); - reg = RW(reg, R92C_TXAGC_A_CCK55, power[2]); - reg = RW(reg, R92C_TXAGC_A_CCK11, power[3]); + reg = RW(reg, R92C_TXAGC_A_CCK2, power[RTWN_POWER_CCK2]); + reg = RW(reg, R92C_TXAGC_A_CCK55, power[RTWN_POWER_CCK55]); + reg = RW(reg, R92C_TXAGC_A_CCK11, power[RTWN_POWER_CCK11]); rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg); } else { reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32); - reg = RW(reg, R92C_TXAGC_B_CCK1, power[0]); - reg = RW(reg, R92C_TXAGC_B_CCK2, power[1]); - reg = RW(reg, R92C_TXAGC_B_CCK55, power[2]); + reg = RW(reg, R92C_TXAGC_B_CCK1, power[RTWN_POWER_CCK1]); + reg = RW(reg, R92C_TXAGC_B_CCK2, power[RTWN_POWER_CCK2]); + reg = RW(reg, R92C_TXAGC_B_CCK55, power[RTWN_POWER_CCK55]); rtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg); reg = rtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11); - reg = RW(reg, R92C_TXAGC_B_CCK11, power[3]); + reg = RW(reg, R92C_TXAGC_B_CCK11, power[RTWN_POWER_CCK11]); rtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg); } /* Write per-OFDM rate Tx power. */ rtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain), - SM(R92C_TXAGC_RATE06, power[ 4]) | - SM(R92C_TXAGC_RATE09, power[ 5]) | - SM(R92C_TXAGC_RATE12, power[ 6]) | - SM(R92C_TXAGC_RATE18, power[ 7])); + SM(R92C_TXAGC_RATE06, power[RTWN_POWER_OFDM6]) | + SM(R92C_TXAGC_RATE09, power[RTWN_POWER_OFDM9]) | + SM(R92C_TXAGC_RATE12, power[RTWN_POWER_OFDM12]) | + SM(R92C_TXAGC_RATE18, power[RTWN_POWER_OFDM18])); rtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain), - SM(R92C_TXAGC_RATE24, power[ 8]) | - SM(R92C_TXAGC_RATE36, power[ 9]) | - SM(R92C_TXAGC_RATE48, power[10]) | - SM(R92C_TXAGC_RATE54, power[11])); + SM(R92C_TXAGC_RATE24, power[RTWN_POWER_OFDM24]) | + SM(R92C_TXAGC_RATE36, power[RTWN_POWER_OFDM36]) | + SM(R92C_TXAGC_RATE48, power[RTWN_POWER_OFDM48]) | + SM(R92C_TXAGC_RATE54, power[RTWN_POWER_OFDM54])); /* Write per-MCS Tx power. */ rtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain), - SM(R92C_TXAGC_MCS00, power[12]) | - SM(R92C_TXAGC_MCS01, power[13]) | - SM(R92C_TXAGC_MCS02, power[14]) | - SM(R92C_TXAGC_MCS03, power[15])); + SM(R92C_TXAGC_MCS00, power[RTWN_POWER_MCS( 0)]) | + SM(R92C_TXAGC_MCS01, power[RTWN_POWER_MCS( 1)]) | + SM(R92C_TXAGC_MCS02, power[RTWN_POWER_MCS( 2)]) | + SM(R92C_TXAGC_MCS03, power[RTWN_POWER_MCS( 3)])); rtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain), - SM(R92C_TXAGC_MCS04, power[16]) | - SM(R92C_TXAGC_MCS05, power[17]) | - SM(R92C_TXAGC_MCS06, power[18]) | - SM(R92C_TXAGC_MCS07, power[19])); + SM(R92C_TXAGC_MCS04, power[RTWN_POWER_MCS( 4)]) | + SM(R92C_TXAGC_MCS05, power[RTWN_POWER_MCS( 5)]) | + SM(R92C_TXAGC_MCS06, power[RTWN_POWER_MCS( 6)]) | + SM(R92C_TXAGC_MCS07, power[RTWN_POWER_MCS( 7)])); rtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain), - SM(R92C_TXAGC_MCS08, power[20]) | - SM(R92C_TXAGC_MCS09, power[21]) | - SM(R92C_TXAGC_MCS10, power[22]) | - SM(R92C_TXAGC_MCS11, power[23])); + SM(R92C_TXAGC_MCS08, power[RTWN_POWER_MCS( 8)]) | + SM(R92C_TXAGC_MCS09, power[RTWN_POWER_MCS( 9)]) | + SM(R92C_TXAGC_MCS10, power[RTWN_POWER_MCS(10)]) | + SM(R92C_TXAGC_MCS11, power[RTWN_POWER_MCS(11)])); rtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain), - SM(R92C_TXAGC_MCS12, power[24]) | - SM(R92C_TXAGC_MCS13, power[25]) | - SM(R92C_TXAGC_MCS14, power[26]) | - SM(R92C_TXAGC_MCS15, power[27])); + SM(R92C_TXAGC_MCS12, power[RTWN_POWER_MCS(12)]) | + SM(R92C_TXAGC_MCS13, power[RTWN_POWER_MCS(13)]) | + SM(R92C_TXAGC_MCS14, power[RTWN_POWER_MCS(14)]) | + SM(R92C_TXAGC_MCS15, power[RTWN_POWER_MCS(15)])); } void -rtwn_get_txpower(struct rtwn_softc *sc, int chain, +rtwn_get_txpower(void *cookie, int chain, struct ieee80211_channel *c, + struct ieee80211_channel *extc, uint16_t power[RTWN_POWER_COUNT]) +{ + struct rtwn_softc *sc = cookie; + + if (sc->chip & RTWN_CHIP_88E) + rtwn_r88e_get_txpower(sc, chain, c, extc, power); + else + rtwn_r92c_get_txpower(sc, chain, c, extc, power); +} + +void +rtwn_r92c_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, struct ieee80211_channel *extc, - uint16_t power[RTWN_RIDX_COUNT]) + uint16_t power[RTWN_POWER_COUNT]) { struct ieee80211com *ic = &sc->sc_ic; - struct r92c_rom *rom = &sc->rom; + struct r92c_rom *rom = &sc->sc_r92c_rom; uint16_t cckpow, ofdmpow, htpow, diff, max; const struct r92c_txpwr *base; int ridx, chan, group; @@ -1850,12 +1873,12 @@ rtwn_get_txpower(struct rtwn_softc *sc, int chain, } else base = &rtl8192cu_txagc[chain]; - memset(power, 0, RTWN_RIDX_COUNT * sizeof(power[0])); + memset(power, 0, RTWN_POWER_COUNT * sizeof(power[0])); if (sc->regulatory == 0) { - for (ridx = 0; ridx <= 3; ridx++) + for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) power[ridx] = base->pwr[0][ridx]; } - for (ridx = 4; ridx < RTWN_RIDX_COUNT; ridx++) { + for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_MAX; ridx++) { if (sc->regulatory == 3) { power[ridx] = base->pwr[0][ridx]; /* Apply vendor limits. */ @@ -1875,7 +1898,7 @@ rtwn_get_txpower(struct rtwn_softc *sc, int chain, /* Compute per-CCK rate Tx power. */ cckpow = rom->cck_tx_pwr[chain][group]; - for (ridx = 0; ridx <= 3; ridx++) { + for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) { power[ridx] += cckpow; if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; @@ -1893,7 +1916,7 @@ rtwn_get_txpower(struct rtwn_softc *sc, int chain, diff = rom->ofdm_tx_pwr_diff[group]; diff = (diff >> (chain * 4)) & 0xf; ofdmpow = htpow + diff; /* HT->OFDM correction. */ - for (ridx = 4; ridx <= 11; ridx++) { + for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++) { power[ridx] += ofdmpow; if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; @@ -1905,7 +1928,7 @@ rtwn_get_txpower(struct rtwn_softc *sc, int chain, diff = (diff >> (chain * 4)) & 0xf; htpow += diff; /* HT40->HT20 correction. */ } - for (ridx = 12; ridx <= 27; ridx++) { + for (ridx = RTWN_RIDX_MCS0; ridx <= RTWN_RIDX_MCS15; ridx++) { power[ridx] += htpow; if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; @@ -1914,7 +1937,7 @@ rtwn_get_txpower(struct rtwn_softc *sc, int chain, if (rtwn_debug >= 4) { /* Dump per-rate Tx power values. */ printf("Tx power for chain %d:\n", chain); - for (ridx = 0; ridx < RTWN_RIDX_COUNT; ridx++) + for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_MAX; ridx++) printf("Rate %d = %u\n", ridx, power[ridx]); } #endif @@ -1923,11 +1946,12 @@ rtwn_get_txpower(struct rtwn_softc *sc, int chain, void rtwn_r88e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, struct ieee80211_channel *extc, - uint16_t power[RTWN_RIDX_COUNT]) + uint16_t power[RTWN_POWER_COUNT]) { struct ieee80211com *ic = &sc->sc_ic; - uint16_t cckpow, ofdmpow, bw20pow, htpow; - const struct r88e_txpwr *base; + struct r88e_rom *rom = &sc->sc_r88e_rom; + uint8_t cckpow, htpow, ofdmpow; + int8_t diff; int ridx, chan, group; /* Determine channel group. */ @@ -1945,45 +1969,37 @@ rtwn_r88e_get_txpower(struct rtwn_softc *sc, int chain, else group = 5; - /* Get original Tx power based on board type and RF chain. */ - base = &rtl8188eu_txagc[chain]; - - memset(power, 0, RTWN_RIDX_COUNT * sizeof(power[0])); - if (sc->regulatory == 0) { - for (ridx = 0; ridx <= 3; ridx++) - power[ridx] = base->pwr[0][ridx]; - } - for (ridx = 4; ridx < RTWN_RIDX_COUNT; ridx++) { - if (sc->regulatory == 3) - power[ridx] = base->pwr[0][ridx]; - else if (sc->regulatory == 1) { - if (extc == NULL) - power[ridx] = base->pwr[group][ridx]; - } else if (sc->regulatory != 2) - power[ridx] = base->pwr[0][ridx]; - } + memset(power, 0, RTWN_POWER_COUNT * sizeof(power[0])); /* Compute per-CCK rate Tx power. */ - cckpow = sc->cck_tx_pwr[group]; - for (ridx = 0; ridx <= 3; ridx++) { - power[ridx] += cckpow; + cckpow = rom->txpwr.cck_tx_pwr[group]; + for (ridx = RTWN_RIDX_CCK1; ridx <= RTWN_RIDX_CCK11; ridx++) { + power[ridx] = (ridx == RTWN_RIDX_CCK2) ? cckpow - 9 : cckpow; if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; } - htpow = sc->ht40_tx_pwr[group]; + if (group < 5) + htpow = rom->txpwr.ht40_tx_pwr[group]; /* Compute per-OFDM rate Tx power. */ - ofdmpow = htpow + sc->ofdm_tx_pwr_diff; - for (ridx = 4; ridx <= 11; ridx++) { - power[ridx] += ofdmpow; + diff = RTWN_SIGN4TO8(MS(rom->txpwr.ht20_ofdm_tx_pwr_diff, + R88E_ROM_TXPWR_OFDM_DIFF)); + ofdmpow = htpow + diff; + for (ridx = RTWN_RIDX_OFDM6; ridx <= RTWN_RIDX_OFDM54; ridx++) { + power[ridx] = ofdmpow; if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; } - bw20pow = htpow + sc->bw20_tx_pwr_diff; - for (ridx = 12; ridx <= 27; ridx++) { - power[ridx] += bw20pow; + /* Compute per-MCS Tx power. */ + if (extc == NULL) { + diff = RTWN_SIGN4TO8(MS(rom->txpwr.ht20_ofdm_tx_pwr_diff, + R88E_ROM_TXPWR_HT20_DIFF)); + htpow += diff; + } + for (ridx = RTWN_RIDX_MCS0; ridx < RTWN_RIDX_MCS8; ridx++) { + power[ridx] = htpow; if (power[ridx] > R92C_MAX_TX_PWR) power[ridx] = R92C_MAX_TX_PWR; } @@ -1993,15 +2009,12 @@ void rtwn_set_txpower(struct rtwn_softc *sc, struct ieee80211_channel *c, struct ieee80211_channel *extc) { - uint16_t power[RTWN_RIDX_COUNT]; + uint16_t power[RTWN_POWER_COUNT]; int i; for (i = 0; i < sc->ntxchains; i++) { /* Compute per-rate Tx power values. */ - if (sc->chip & RTWN_CHIP_88E) - rtwn_r88e_get_txpower(sc, i, c, extc, power); - else - rtwn_get_txpower(sc, i, c, extc, power); + rtwn_get_txpower(sc, i, c, extc, power); /* Write per-rate Tx power values to hardware. */ rtwn_write_txpower(sc, i, power); } diff --git a/sys/dev/ic/rtwnvar.h b/sys/dev/ic/rtwnvar.h index f7c57c68fab..6165b043811 100644 --- a/sys/dev/ic/rtwnvar.h +++ b/sys/dev/ic/rtwnvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rtwnvar.h,v 1.8 2017/01/30 21:54:30 stsp Exp $ */ +/* $OpenBSD: rtwnvar.h,v 1.9 2017/06/16 14:57:51 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -43,6 +43,10 @@ struct rtwn_ops { void (*next_scan)(void *); void (*cancel_scan)(void *); void (*wait_async)(void *); + + void (*get_txpower)(void *, int, struct ieee80211_channel *, + struct ieee80211_channel *, uint16_t[]); + void (*read_rom)(void *); }; #define RTWN_LED_LINK 0 @@ -67,6 +71,7 @@ struct rtwn_softc { #define RTWN_FLAG_CCK_HIPWR 0x01 #define RTWN_FLAG_BUSY 0x02 #define RTWN_FLAG_FORCE_RAID_11B 0x04 +#define RTWN_FLAG_EXT_HDR 0x08 uint32_t chip; #define RTWN_CHIP_92C 0x00000001 @@ -80,6 +85,7 @@ struct rtwn_softc { #define RTWN_CHIP_USB 0x80000000 uint8_t board_type; + uint8_t crystal_cap; uint8_t regulatory; uint8_t pa_setting; int avg_pwdb; @@ -91,18 +97,17 @@ struct rtwn_softc { int sc_tx_timer; int fwcur; - struct r92c_rom rom; - - uint8_t r88e_rom[512]; - uint8_t cck_tx_pwr[6]; - uint8_t ht40_tx_pwr[5]; - int8_t bw20_tx_pwr_diff; - int8_t ofdm_tx_pwr_diff; + union { + struct r92c_rom r92c_rom; + struct r88e_rom r88e_rom; + } u; +#define sc_r92c_rom u.r92c_rom +#define sc_r88e_rom u.r88e_rom uint32_t rf_chnlbw[R92C_MAX_CHAINS]; }; -int rtwn_attach(struct device *, struct rtwn_softc *, uint32_t); +int rtwn_attach(struct device *, struct rtwn_softc *); int rtwn_detach(struct rtwn_softc *, int); int rtwn_activate(struct rtwn_softc *, int); int8_t rtwn_get_rssi(struct rtwn_softc *, int, void *); diff --git a/sys/dev/pci/if_rtwn.c b/sys/dev/pci/if_rtwn.c index 754af774d44..1a74b76960a 100644 --- a/sys/dev/pci/if_rtwn.c +++ b/sys/dev/pci/if_rtwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_rtwn.c,v 1.28 2017/05/19 11:30:40 stsp Exp $ */ +/* $OpenBSD: if_rtwn.c,v 1.29 2017/06/16 14:57:51 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -371,8 +371,10 @@ rtwn_pci_attach(struct device *parent, struct device *self, void *aux) sc->sc_sc.sc_ops.next_scan = rtwn_pci_next_scan; sc->sc_sc.sc_ops.cancel_scan = rtwn_cancel_scan; sc->sc_sc.sc_ops.wait_async = rtwn_wait_async; - error = rtwn_attach(&sc->sc_dev, &sc->sc_sc, - RTWN_CHIP_88C | RTWN_CHIP_PCI); + + sc->sc_sc.chip = RTWN_CHIP_88C | RTWN_CHIP_PCI; + + error = rtwn_attach(&sc->sc_dev, &sc->sc_sc); if (error != 0) { rtwn_free_rx_list(sc); for (i = 0; i < RTWN_NTXQUEUES; i++) diff --git a/sys/dev/usb/if_urtwn.c b/sys/dev/usb/if_urtwn.c index a22be514f64..039f4d16526 100644 --- a/sys/dev/usb/if_urtwn.c +++ b/sys/dev/usb/if_urtwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_urtwn.c,v 1.70 2017/05/08 12:28:39 stsp Exp $ */ +/* $OpenBSD: if_urtwn.c,v 1.71 2017/06/16 14:57:51 kevlo Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini @@ -204,96 +204,110 @@ int urtwn_debug = 4; #define DPRINTFN(n, x) #endif -static const struct usb_devno urtwn_devs[] = { - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_1 }, - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_2 }, - { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8192CU }, - { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU }, - { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU_2 }, - { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU_3 }, - { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_1 }, - { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_2 }, - { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CU }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D2102 }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F9L1004V1 }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CU }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CUS }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU_1 }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU_2 }, - { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_1 }, - { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_2 }, - { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_3 }, - { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_4 }, - { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_5 }, - { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_6 }, - { USB_VENDOR_COMPARE, USB_PRODUCT_COMPARE_RTL8192CU }, - { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192CU }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA131B }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8188CU }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_1 }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_2 }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_3 }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_4 }, - { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_EW7811UN }, - { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192CU }, - { USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8188CU }, - { USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8192CU }, - { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUP150 }, - { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_RTL8192CU }, - { USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU }, - { USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU_2 }, - { USB_VENDOR_HP3, USB_PRODUCT_HP3_RTL8188CU }, - { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNG150UM }, - { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_RTL8192CU }, - { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_N300MA }, - { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000M }, - { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000Mv2 }, - { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_RTL8192CU }, - { USB_VENDOR_NETGEAR4, USB_PRODUCT_NETGEAR4_RTL8188CU }, - { USB_VENDOR_NETWEEN, USB_PRODUCT_NETWEEN_RTL8192CU }, - { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RTL8188CU }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_1 }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_2 }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_3 }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_4 }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CUS }, - { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8192CU }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_1 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_0 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_1 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_2 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_3 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_4 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_5 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_COMBO }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CUS }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_2 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_3 }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8191CU }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE_VAU }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CU }, - { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU }, - { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_2 }, - { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU }, - { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU_2 }, - { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WLA2100V2 }, - { USB_VENDOR_TPLINK, USB_PRODUCT_TPLINK_RTL8192CU }, - { USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU }, - { USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8192CU }, - { USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU }, +/* + * Various supported device vendors/products. + */ +#define URTWN_DEV(v, p, f) \ + { { USB_VENDOR_##v, USB_PRODUCT_##v##_##p }, (f) | RTWN_CHIP_USB } +#define URTWN_DEV_8192CU(v, p) URTWN_DEV(v, p, RTWN_CHIP_92C | RTWN_CHIP_88C) +#define URTWN_DEV_8188EU(v, p) URTWN_DEV(v, p, RTWN_CHIP_88E) +static const struct urtwn_type { + struct usb_devno dev; + uint32_t chip; +} urtwn_devs[] = { + URTWN_DEV_8192CU(ABOCOM, RTL8188CU_1), + URTWN_DEV_8192CU(ABOCOM, RTL8188CU_1), + URTWN_DEV_8192CU(ABOCOM, RTL8188CU_2), + URTWN_DEV_8192CU(ABOCOM, RTL8192CU), + URTWN_DEV_8192CU(ASUS, RTL8192CU), + URTWN_DEV_8192CU(ASUS, RTL8192CU_2), + URTWN_DEV_8192CU(ASUS, RTL8192CU_3), + URTWN_DEV_8192CU(AZUREWAVE, RTL8188CE_1), + URTWN_DEV_8192CU(AZUREWAVE, RTL8188CE_2), + URTWN_DEV_8192CU(AZUREWAVE, RTL8188CU), + URTWN_DEV_8192CU(BELKIN, F7D2102), + URTWN_DEV_8192CU(BELKIN, F9L1004V1), + URTWN_DEV_8192CU(BELKIN, RTL8188CU), + URTWN_DEV_8192CU(BELKIN, RTL8188CUS), + URTWN_DEV_8192CU(BELKIN, RTL8192CU), + URTWN_DEV_8192CU(BELKIN, RTL8192CU_1), + URTWN_DEV_8192CU(BELKIN, RTL8192CU_2), + URTWN_DEV_8192CU(CHICONY, RTL8188CUS_1), + URTWN_DEV_8192CU(CHICONY, RTL8188CUS_2), + URTWN_DEV_8192CU(CHICONY, RTL8188CUS_3), + URTWN_DEV_8192CU(CHICONY, RTL8188CUS_4), + URTWN_DEV_8192CU(CHICONY, RTL8188CUS_5), + URTWN_DEV_8192CU(CHICONY, RTL8188CUS_6), + URTWN_DEV_8192CU(COMPARE, RTL8192CU), + URTWN_DEV_8192CU(COREGA, RTL8192CU), + URTWN_DEV_8192CU(DLINK, DWA131B), + URTWN_DEV_8192CU(DLINK, RTL8188CU), + URTWN_DEV_8192CU(DLINK, RTL8192CU_1), + URTWN_DEV_8192CU(DLINK, RTL8192CU_2), + URTWN_DEV_8192CU(DLINK, RTL8192CU_3), + URTWN_DEV_8192CU(DLINK, RTL8192CU_4), + URTWN_DEV_8192CU(EDIMAX, EW7811UN), + URTWN_DEV_8192CU(EDIMAX, RTL8192CU), + URTWN_DEV_8192CU(FEIXUN, RTL8188CU), + URTWN_DEV_8192CU(FEIXUN, RTL8192CU), + URTWN_DEV_8192CU(GUILLEMOT, HWNUP150), + URTWN_DEV_8192CU(GUILLEMOT, RTL8192CU), + URTWN_DEV_8192CU(HAWKING, RTL8192CU), + URTWN_DEV_8192CU(HAWKING, RTL8192CU_2), + URTWN_DEV_8192CU(HP3, RTL8188CU), + URTWN_DEV_8192CU(IODATA, WNG150UM), + URTWN_DEV_8192CU(IODATA, RTL8192CU), + URTWN_DEV_8192CU(NETGEAR, N300MA), + URTWN_DEV_8192CU(NETGEAR, WNA1000M), + URTWN_DEV_8192CU(NETGEAR, WNA1000Mv2), + URTWN_DEV_8192CU(NETGEAR, RTL8192CU), + URTWN_DEV_8192CU(NETGEAR4, RTL8188CU), + URTWN_DEV_8192CU(NETWEEN, RTL8192CU), + URTWN_DEV_8192CU(NOVATECH, RTL8188CU), + URTWN_DEV_8192CU(PLANEX2, RTL8188CU_1), + URTWN_DEV_8192CU(PLANEX2, RTL8188CU_2), + URTWN_DEV_8192CU(PLANEX2, RTL8188CU_3), + URTWN_DEV_8192CU(PLANEX2, RTL8188CU_4), + URTWN_DEV_8192CU(PLANEX2, RTL8188CUS), + URTWN_DEV_8192CU(PLANEX2, RTL8192CU), + URTWN_DEV_8192CU(REALTEK, RTL8188CE_0), + URTWN_DEV_8192CU(REALTEK, RTL8188CE_1), + URTWN_DEV_8192CU(REALTEK, RTL8188CTV), + URTWN_DEV_8192CU(REALTEK, RTL8188CU_0), + URTWN_DEV_8192CU(REALTEK, RTL8188CU_1), + URTWN_DEV_8192CU(REALTEK, RTL8188CU_2), + URTWN_DEV_8192CU(REALTEK, RTL8188CU_3), + URTWN_DEV_8192CU(REALTEK, RTL8188CU_4), + URTWN_DEV_8192CU(REALTEK, RTL8188CU_5), + URTWN_DEV_8192CU(REALTEK, RTL8188CU_COMBO), + URTWN_DEV_8192CU(REALTEK, RTL8188CUS), + URTWN_DEV_8192CU(REALTEK, RTL8188RU), + URTWN_DEV_8192CU(REALTEK, RTL8188RU_2), + URTWN_DEV_8192CU(REALTEK, RTL8188RU_3), + URTWN_DEV_8192CU(REALTEK, RTL8191CU), + URTWN_DEV_8192CU(REALTEK, RTL8192CE), + URTWN_DEV_8192CU(REALTEK, RTL8192CE_VAU), + URTWN_DEV_8192CU(REALTEK, RTL8192CU), + URTWN_DEV_8192CU(SITECOMEU, RTL8188CU), + URTWN_DEV_8192CU(SITECOMEU, RTL8188CU_2), + URTWN_DEV_8192CU(SITECOMEU, RTL8192CU), + URTWN_DEV_8192CU(SITECOMEU, RTL8192CU_2), + URTWN_DEV_8192CU(SITECOMEU, WLA2100V2), + URTWN_DEV_8192CU(TPLINK, RTL8192CU), + URTWN_DEV_8192CU(TRENDNET, RTL8188CU), + URTWN_DEV_8192CU(TRENDNET, RTL8192CU), + URTWN_DEV_8192CU(ZYXEL, RTL8192CU), /* URTWN_RTL8188E */ - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA123D1 }, - { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWA125D1 }, - { USB_VENDOR_ELECOM, USB_PRODUCT_ELECOM_WDC150SU2M }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188ETV }, - { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188EU } + URTWN_DEV_8188EU(DLINK, DWA123D1), + URTWN_DEV_8188EU(DLINK, DWA125D1), + URTWN_DEV_8188EU(ELECOM, WDC150SU2M), + URTWN_DEV_8188EU(REALTEK, RTL8188ETV), + URTWN_DEV_8188EU(REALTEK, RTL8188EU) }; +#define urtwn_lookup(v, p) \ + ((const struct urtwn_type *)usb_lookup(urtwn_devs, v, p)) + int urtwn_match(struct device *, void *, void *); void urtwn_attach(struct device *, struct device *, void *); int urtwn_detach(struct device *, int); @@ -381,7 +395,7 @@ urtwn_match(struct device *parent, void *match, void *aux) if (uaa->iface == NULL || uaa->configno != 1) return (UMATCH_NONE); - return ((usb_lookup(urtwn_devs, uaa->vendor, uaa->product) != NULL) ? + return ((urtwn_lookup(uaa->vendor, uaa->product) != NULL) ? UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE); } @@ -392,27 +406,18 @@ urtwn_attach(struct device *parent, struct device *self, void *aux) struct usb_attach_arg *uaa = aux; struct ifnet *ifp; struct ieee80211com *ic = &sc->sc_sc.sc_ic; - uint32_t chip_type; sc->sc_udev = uaa->device; sc->sc_iface = uaa->iface; + sc->sc_sc.chip = urtwn_lookup(uaa->vendor, uaa->product)->chip; + usb_init_task(&sc->sc_task, urtwn_task, sc, USB_TASK_TYPE_GENERIC); timeout_set(&sc->scan_to, urtwn_scan_to, sc); timeout_set(&sc->calib_to, urtwn_calib_to, sc); if (urtwn_open_pipes(sc) != 0) return; - chip_type = RTWN_CHIP_USB; - if (uaa->product == USB_PRODUCT_DLINK_DWA123D1 || - uaa->product == USB_PRODUCT_DLINK_DWA125D1 || - uaa->product == USB_PRODUCT_ELECOM_WDC150SU2M || - uaa->product == USB_PRODUCT_REALTEK_RTL8188EU || - uaa->product == USB_PRODUCT_REALTEK_RTL8188ETV) - chip_type |= RTWN_CHIP_88E; - else - chip_type |= (RTWN_CHIP_92C | RTWN_CHIP_88C); - sc->amrr.amrr_min_success_threshold = 1; sc->amrr.amrr_max_success_threshold = 10; @@ -440,7 +445,7 @@ urtwn_attach(struct device *parent, struct device *self, void *aux) sc->sc_sc.sc_ops.next_scan = urtwn_next_scan; sc->sc_sc.sc_ops.cancel_scan = urtwn_cancel_scan; sc->sc_sc.sc_ops.wait_async = urtwn_wait_async; - if (rtwn_attach(&sc->sc_dev, &sc->sc_sc, chip_type) != 0) { + if (rtwn_attach(&sc->sc_dev, &sc->sc_sc) != 0) { urtwn_close_pipes(sc); return; } @@ -1579,7 +1584,6 @@ urtwn_r88e_power_on(struct urtwn_softc *sc) urtwn_read_1(sc, R92C_AFE_XTAL_CTRL + 2) | 0x80); /* Disable HWPDN. */ - urtwn_write_1(sc, 0x5, urtwn_read_1(sc, 0x5) & ~0x80); urtwn_write_2(sc, R92C_APS_FSMCO, urtwn_read_2(sc, R92C_APS_FSMCO) & ~R92C_APS_FSMCO_APDM_HPDN); @@ -1862,7 +1866,7 @@ urtwn_bb_init(void *cookie) struct urtwn_softc *sc = cookie; const struct r92c_bb_prog *prog; uint32_t reg; - uint8_t crystalcap; + uint8_t xtal; int i; /* Enable BB and RF. */ @@ -1960,14 +1964,10 @@ urtwn_bb_init(void *cookie) urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), 0x69553420); DELAY(1); - crystalcap = sc->sc_sc.r88e_rom[0xb9]; - if (crystalcap == 0xff) - crystalcap = 0x20; - crystalcap &= 0x3f; + xtal = sc->sc_sc.crystal_cap & 0x3f; reg = urtwn_bb_read(sc, R92C_AFE_XTAL_CTRL); urtwn_bb_write(sc, R92C_AFE_XTAL_CTRL, - RW(reg, R92C_AFE_XTAL_CTRL_ADDR, - crystalcap | crystalcap << 6)); + RW(reg, R92C_AFE_XTAL_CTRL_ADDR, xtal | xtal << 6)); } if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) & R92C_HSSI_PARAM2_CCK_HIPWR) @@ -1980,9 +1980,9 @@ urtwn_power_on(void *cookie) struct urtwn_softc *sc = cookie; if (sc->sc_sc.chip & RTWN_CHIP_88E) - return urtwn_r88e_power_on(sc); + return (urtwn_r88e_power_on(sc)); - return urtwn_r92c_power_on(sc); + return (urtwn_r92c_power_on(sc)); } int