diff options
author | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2018-12-04 10:47:33 +0000 |
---|---|---|
committer | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2018-12-04 10:47:33 +0000 |
commit | 0cf530cb1e36e672c7a8cbef6f1b9b834e20c675 (patch) | |
tree | 93e1c9f8eb46d05134a4cbe18055e1a5335d0f99 /sys/dev/ic | |
parent | 2975b01a5b89f23dc156323c95b38cbbbc45ffc0 (diff) |
Add support for RTL8192EU adapters, partly taken from netbsd.
These show up with a variety of vendor/product ids, but the driver will
only match those we've tested so far.
help and testing from kevlo@
ok stsp@ kevlo@
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/r92creg.h | 424 | ||||
-rw-r--r-- | sys/dev/ic/rtwn.c | 575 | ||||
-rw-r--r-- | sys/dev/ic/rtwnvar.h | 4 |
3 files changed, 871 insertions, 132 deletions
diff --git a/sys/dev/ic/r92creg.h b/sys/dev/ic/r92creg.h index 68bc56b834a..6adabc733ef 100644 --- a/sys/dev/ic/r92creg.h +++ b/sys/dev/ic/r92creg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: r92creg.h,v 1.21 2018/10/01 22:36:08 jmatthew Exp $ */ +/* $OpenBSD: r92creg.h,v 1.22 2018/12/04 10:47:32 jmatthew Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> @@ -31,6 +31,7 @@ #define R92C_SYS_CLKR 0x008 #define R92C_AFE_MISC 0x010 #define R92C_SPS0_CTRL 0x011 +#define R92C_SYS_SWR_CTRL2 0x014 #define R92C_SPS_OCP_CFG 0x018 #define R92C_RSV_CTRL 0x01c #define R92C_RF_CTRL 0x01f @@ -40,6 +41,7 @@ #define R92C_LPLDO_CTRL 0x023 #define R92C_AFE_XTAL_CTRL 0x024 #define R92C_AFE_PLL_CTRL 0x028 +#define R92C_AFE_CTRL3 0x02c #define R92C_EFUSE_CTRL 0x030 #define R92C_EFUSE_TEST 0x034 #define R92C_PWR_DATA 0x038 @@ -60,6 +62,7 @@ #define R92C_HSISR 0x05c #define R92C_AFE_XTAL_CTRL_EXT 0x078 #define R88E_XCK_OUT_CTRL 0x07c +#define R92E_LDO_SWR_CTRL 0x07c #define R92C_MCUFWDL 0x080 #define R92C_HMEBOX_EXT(idx) (0x088 + (idx) * 2) #define R88E_HIMR 0x0b0 @@ -117,11 +120,14 @@ #define R92C_TXDMA_OFFSET_CHK 0x20c #define R92C_TXDMA_STATUS 0x210 #define R92C_RQPN_NPQ 0x214 +#define R92E_AUTO_LLT 0x224 +#define R92E_DWBCN1_CTRL 0x228 /* Rx DMA Configuration. */ #define R92C_RXDMA_AGG_PG_TH 0x280 #define R92C_RXPKT_NUM 0x284 #define R88E_RXDMA_CTRL 0x286 #define R92C_RXDMA_STATUS 0x288 +#define R92E_RXDMA_PRO 0x290 #define R92C_PCIE_CTRL_REG 0x300 #define R92C_INT_MIG 0x304 @@ -168,8 +174,11 @@ #define R92C_FAST_EDCA_CTRL 0x460 #define R92C_RD_RESP_PKT_TH 0x463 #define R92C_INIRTS_RATE_SEL 0x480 +#define R92E_DATA_SC 0x483 #define R92C_INIDATA_RATE_SEL(macid) (0x484 + (macid)) +#define R92C_QUEUE_CTRL 0x4c6 #define R92C_MAX_AGGR_NUM 0x4ca +#define R92C_BAR_MODE_CTRL 0x4cc #define R88E_TX_RPT_CTRL 0x4ec #define R88E_TX_RPT_TIME 0x4f0 /* EDCA Configuration. */ @@ -229,6 +238,7 @@ #define R92C_RESP_SIFS_CCK 0x63c #define R92C_RESP_SIFS_OFDM 0x63e #define R92C_ACKTO 0x640 +#define R92C_NAV_UPPER 0x652 #define R92C_WMAC_TRXPTCL_CTL 0x668 #define R92C_CAMCMD 0x670 #define R92C_CAMWRITE 0x674 @@ -239,6 +249,9 @@ #define R92C_RXFLTMAP1 0x6a2 #define R92C_RXFLTMAP2 0x6a4 +#define R92C_CONFIG_ANT_A 0xb68 +#define R92C_CONFIG_ANT_B 0xb6c + /* Bits for R92C_SYS_ISO_CTRL. */ #define R92C_SYS_ISO_CTRL_MD2PP 0x0001 #define R92C_SYS_ISO_CTRL_UA2USB 0x0002 @@ -321,6 +334,7 @@ #define R92C_RSV_CTRL_R_DIS_PRST_0 0x20 #define R92C_RSV_CTRL_R_DIS_PRST_1 0x40 #define R92C_RSV_CTRL_LOCK_ALL_EN 0x80 +#define R88E_RSV_CTRL_MIO_EN 0x0100 /* Bits for R92C_RF_CTRL. */ #define R92C_RF_CTRL_EN 0x01 @@ -355,6 +369,9 @@ /* Bits for R92C_LEDCFG0. */ #define R92C_LEDCFG0_DIS 0x08 +/* Bits for R92C_LEDCFG1. */ +#define R92E_LEDSON 0x60 + /* Bits for R92C_LEDCFG2. */ #define R92C_LEDCFG2_EN 0x60 #define R92C_LEDCFG2_DIS 0x68 @@ -440,6 +457,7 @@ #define R92C_SYS_CFG_PAD_HWPD_IDN 0x00400000 #define R92C_SYS_CFG_TRP_VAUX_EN 0x00800000 #define R92C_SYS_CFG_TRP_BT_EN 0x01000000 +#define R92E_SYS_CFG_SPSLDO_SEL 0x01000000 #define R92C_SYS_CFG_BD_PKG_SEL 0x02000000 #define R92C_SYS_CFG_BD_HCI_SEL 0x04000000 #define R92C_SYS_CFG_TYPE_92C 0x08000000 @@ -511,6 +529,7 @@ #define R92C_LLT_INIT_OP_S 30 #define R92C_LLT_INIT_OP_NO_ACTIVE 0 #define R92C_LLT_INIT_OP_WRITE 1 +#define R92C_LLT_INIT_OP_READ 2 /* Bits for R92C_RQPN. */ #define R92C_RQPN_HPQ_M 0x000000ff @@ -525,6 +544,9 @@ #define R92C_TDECTRL_BLK_DESC_NUM_M 0x000000f0 #define R92C_TDECTRL_BLK_DESC_NUM_S 4 +/* Bits for R92E_AUTO_LLT. */ +#define R92E_AUTO_LLT_EN 0x00010000 + /* Bits for R92C_FWHW_TXQ_CTRL. */ #define R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW 0x80 @@ -648,6 +670,12 @@ /* Bits for R92C_WMAC_TRXPTCL_CTL. */ #define R92C_WMAC_TRXPTCL_CTL_SHORT 0x00020000 +#define R92C_WMAC_TRXPTCL_CTL_BW_20 0 +#define R92C_WMAC_TRXPTCL_CTL_BW_40 0x00000080 +#define R92C_WMAC_TRXPTCL_CTL_BW_80 0x00000100 +#define R92C_WMAC_TRXPTCL_CTL_BW_MASK \ + (R92C_WMAC_TRXPTCL_CTL_BW_40 | \ + R92C_WMAC_TRXPTCL_CTL_BW_80) /* Bits for R92C_CAMCMD. */ #define R92C_CAMCMD_ADDR_M 0x0000ffff @@ -731,6 +759,7 @@ */ #define R92C_FPGA0_RFMOD 0x800 #define R92C_FPGA0_TXINFO 0x804 +#define R92C_FPGA0_POWER_SAVE 0x818 #define R92C_HSSI_PARAM1(chain) (0x820 + (chain) * 8) #define R92C_HSSI_PARAM2(chain) (0x824 + (chain) * 8) #define R92C_TXAGC_RATE18_06(i) (((i) == 0) ? 0xe00 : 0x830) @@ -763,8 +792,33 @@ #define R92C_OFDM0_TXIQIMBALANCE(chain) (0xc80 + (chain) * 8) #define R92C_OFDM0_TXAFE(chain) (0xc94 + (chain) * 8) #define R92C_OFDM0_RXIQEXTANTA 0xca0 +#define R92C_OFDM0_TX_PSDO_NOISE_WEIGHT 0xce4 #define R92C_OFDM1_LSTF 0xd00 +#define R92C_FPGA0_IQK 0xe28 +#define R92C_TX_IQK_TONE_A 0xe30 +#define R92C_RX_IQK_TONE_A 0xe34 +#define R92C_TX_IQK_PI_A 0xe38 +#define R92C_RX_IQK_PI_A 0xe3c +#define R92C_TX_IQK 0xe40 +#define R92C_RX_IQK 0xe44 +#define R92C_IQK_AGC_PTS 0xe48 +#define R92C_IQK_AGC_RSP 0xe4c +#define R92C_TX_IQK_TONE_B 0xe50 +#define R92C_RX_IQK_TONE_B 0xe54 +#define R92C_TX_IQK_PI_B 0xe58 +#define R92C_RX_IQK_PI_B 0xe5c +#define R92C_IQK_AGC_CONT 0xe60 + +#define R92E_RX_WAIT_CCA 0xe70 + +#define R92C_TX_POWER_BEFORE_IQK_A 0xe94 +#define R92C_TX_POWER_AFTER_IQK_A 0xe9c +#define R92C_RX_POWER_BEFORE_IQK_A 0xea0 +#define R92C_RX_POWER_BEFORE_IQK_A_2 0xea4 +#define R92C_RX_POWER_AFTER_IQK_A 0xea8 +#define R92C_RX_POWER_AFTER_IQK_A_2 0xeac + /* Bits for R92C_FPGA[01]_RFMOD. */ #define R92C_RFMOD_40MHZ 0x00000001 #define R92C_RFMOD_JAPAN 0x00000002 @@ -915,7 +969,6 @@ #define R92C_USB_EP_LQ_M 0x0f00 #define R92C_USB_EP_LQ_S 8 - /* * Firmware base address. */ @@ -953,6 +1006,7 @@ #define R92C_RF_SYN_G(i) (0x25 + (i)) #define R92C_RF_RCK_OS 0x30 #define R92C_RF_TXPA_G(i) (0x31 + (i)) +#define R92E_RF_T_METER 0x42 /* Bits for R92C_RF_AC. */ #define R92C_RF_AC_MODE_M 0x70000 @@ -997,6 +1051,10 @@ #define R92C_RAID_11G 5 /* "pure" 11g */ #define R92C_RAID_11B 6 +#define R92E_RAID_11BG 6 +#define R92E_RAID_11G 7 /* "pure" 11g */ +#define R92E_RAID_11B 8 + /* Macros to access unaligned little-endian memory. */ #define LE_READ_2(x) ((x)[0] | (x)[1] << 8) @@ -1076,6 +1134,50 @@ struct r92c_fw_cmd_macid_cfg { #define R92C_MACID_BSS 0 #define R92C_MACID_BC 4 /* Broadcast. */ #define R92C_MACID_VALID 0x80 +#define R92C_MACID_SHORTGI 0x20 +} __packed; + +/* Structure for R92C_CMD_SET_PWRMODE. */ +struct r92c_fw_cmd_setpwrmode { + uint8_t mode; + uint8_t smartps; + uint8_t bcn_time; /* 100ms increments */ +} __packed; + +#define R92E_CMD_KEEP_ALIVE 0x03 +#define R92E_CMD_SET_PWRMODE 0x20 +#define R92E_CMD_RSSI_REPORT 0x42 + +/* Structure for R92E_CMD_KEEP_ALIVE. */ +struct r92e_fw_cmd_keepalive { + uint8_t mode; + uint8_t period; +} __packed; + +/* Structure for R92E_CMD_SET_PWRMODE. */ +struct r92e_fw_cmd_setpwrmode { + uint8_t mode; +#define FWMODE_ACTIVE 0 +#define FWMODE_LOW_POWER 1 +#define FWMODE_WMMPS 2 + uint8_t smartps; +#define SRTPS_LOW_POWER 0 +#define SRTPS_POLL 0x10 +#define SRTPS_WMMPS 0x20 + uint8_t awake_int; /* 100ms increments. */ + uint8_t all_queue_apsd; + uint8_t pwr_state; +#define PS_PFOFF 0x00 +#define PS_RFON 0x04 +#define PS_ALLON 0x0c +} __packed; + +/* Structure for R92E_CMD_RSSI_REPORT. */ +struct r92e_fw_cmd_rssi { + uint8_t macid; + uint8_t reserved; + uint8_t pwdb; + uint8_t reserved2; } __packed; /* @@ -1125,6 +1227,57 @@ struct r92c_rom { uint8_t curstomer_id; } __packed; +struct r92e_tx_pwr { + uint8_t cck_tx_pwr[6]; + uint8_t ht40_tx_pwr[5]; + uint8_t ht20_ofdm_tx_pwr_diff; +#define R92E_ROM_TXPWR_HT20_DIFF_M 0xf0 +#define R92E_ROM_TXPWR_HT20_DIFF_S 4 +#define R92E_ROM_TXPWR_OFDM_DIFF_M 0x0f +#define R92E_ROM_TXPWR_OFDM_DIFF_S 0 + uint16_t pwr_diff[3]; + uint8_t reserved[24]; +} __packed; + +struct r92e_rom { + uint16_t id; + uint8_t reserved[14]; + struct r92e_tx_pwr txpwr_a; + struct r92e_tx_pwr txpwr_b; + uint8_t reserved2[84]; + uint8_t channel_plan; + uint8_t xtal_k; + uint8_t thermal_meter; + uint8_t iqk_lck; + uint8_t pa_type; + uint8_t lna_type_2g; + uint8_t reserved3; + uint8_t lna_type_5g; + uint8_t reserved4; + uint8_t rf_board_opt; + uint8_t rf_feature_opt; + uint8_t rf_bt_opt; + uint8_t eeprom_version; + uint8_t eeprom_customer_id; + uint8_t reserved5[3]; + uint8_t rf_antenna_option; + uint8_t reserved6[6]; + uint16_t vid; + uint16_t pid; + uint8_t usb_optional_function; + uint8_t reserved9[2]; + uint8_t macaddr[IEEE80211_ADDR_LEN]; + uint8_t reserved10[2]; + uint8_t vendor[7]; + uint8_t reserved11[2]; + uint8_t device_name[11]; + uint8_t reserved12[2]; + uint8_t serial[11]; + uint8_t reserved13[48]; + uint8_t unknown[13]; + uint8_t reserved14[195]; +} __packed; + struct r88e_tx_pwr { uint8_t cck_tx_pwr[6]; uint8_t ht40_tx_pwr[5]; @@ -1342,6 +1495,7 @@ struct r92c_rx_desc_usb { #define R92C_RXDW2_PKTCNT_M 0x00ff0000 #define R92C_RXDW2_PKTCNT_S 16 +#define R92E_RXDW2_RPT_C2H 0x10000000 #define R92C_RXDW3_RATE_M 0x0000003f #define R92C_RXDW3_RATE_S 0 @@ -1387,6 +1541,21 @@ struct r92c_tx_desc_usb { uint16_t pad; } __packed __attribute__((aligned(4))); +struct r92e_tx_desc_usb { + uint32_t txdw0; + uint32_t txdw1; + uint32_t txdw2; + uint32_t txdw3; + uint32_t txdw4; + uint32_t txdw5; + uint32_t txdw6; + uint16_t txdsum; + uint16_t pad; + uint32_t txdw7; + uint16_t txdseq2; + uint16_t txdw8; +} __packed __attribute__((aligned(4))); + #define R92C_TXDW0_PKTLEN_M 0x0000ffff #define R92C_TXDW0_PKTLEN_S 0 #define R92C_TXDW0_OFFSET_M 0x00ff0000 @@ -1400,6 +1569,8 @@ struct r92c_tx_desc_usb { #define R92C_TXDW1_MACID_S 0 #define R88E_TXDW1_MACID_M 0x0000003f #define R88E_TXDW1_MACID_S 0 +#define R92E_TXDW1_MACID_M 0x0000007f +#define R92E_TXDW1_MACID_S 0 #define R92C_TXDW1_AGGEN 0x00000020 #define R92C_TXDW1_AGGBK 0x00000040 #define R92C_TXDW1_QSEL_M 0x00001f00 @@ -1425,6 +1596,7 @@ struct r92c_tx_desc_usb { #define R88E_TXDW2_AGGBK 0x00010000 #define R92C_TXDW2_CCX_RPT 0x00080000 +#define R92E_TXDW3_DRVRATE 0x1000 #define R23A_TXDW3_TXRPTEN 0x4000 #define R92C_TXDW3_HWSEQEN 0x8000 @@ -1444,6 +1616,18 @@ struct r92c_tx_desc_usb { #define R92C_TXDW4_40MHZ 0x02000000 #define R92C_TXDW4_RTS_SHORT 0x04000000 +#define R92E_TXDW4_DATARATE_M 0x0000007f +#define R92E_TXDW4_DATARATE_S 0 +#define R92E_TXDW4_DATARATEFB_M 0x00001f00 +#define R92E_TXDW4_DATARATEFB_S 8 +#define R92E_TXDW4_RTSRATEFB_M 0x0001e000 +#define R92E_TXDW4_RTSRATEFB_S 13 +#define R92E_TXDW4_RETRYLMT_ENA 0x00020000 +#define R92E_TXDW4_RETRYLMT_M 0x00fc0000 +#define R92E_TXDW4_RETRYLMT_S 18 +#define R92E_TXDW4_RTSRATE_M 0x1f000000 +#define R92E_TXDW4_RTSRATE_S 24 + #define R92C_TXDW5_DATARATE_M 0x0000003f #define R92C_TXDW5_DATARATE_S 0 #define R92C_TXDW5_SGI 0x00000040 @@ -1457,6 +1641,9 @@ struct r92c_tx_desc_usb { #define R92C_TXDW5_AGGNUM_M 0xff000000 #define R92C_TXDW5_AGGNUM_S 24 +#define R92E_TXDSEQ2_HWSEQ_S 11 +#define R92E_TXDSEQ2_HWSEQ_M 0x0000ffff + /* * C2H event structure. */ @@ -1522,6 +1709,26 @@ struct r92c_c2h_tx_rpt { #define R92C_RPTB7_INT_CCX 0x80 } __packed; +struct r92e_c2h_tx_rpt { + uint8_t rptb0; +#define R92E_RPTB0_QSEL_M 0x1f +#define R92E_RPTB0_QSEL_S 0 +#define R92E_RPTB0_BC 0x20 +#define R92E_RPTB0_LIFE_EXPIRE 0x40 +#define R92E_RPTB0_RETRY_OVER 0x80 + + uint8_t macid; + + uint8_t rptb2; +#define R92E_RPTB2_RETRY_CNT_M 0x3f +#define R92E_RPTB2_RETRY_CNT_S 0 + + uint8_t queue_time_low; + uint8_t queue_time_high; + uint8_t final_rate; + uint16_t reserved; +} __packed; + /* * MAC initialization values. */ @@ -1597,6 +1804,33 @@ static const struct { { 0x63f, 0x0e }, { 0x66e, 0x05 }, { 0x700, 0x21 }, { 0x701, 0x43 }, { 0x702, 0x65 }, { 0x703, 0x87 }, { 0x708, 0x21 }, { 0x709, 0x43 }, { 0x70a, 0x65 }, { 0x70b, 0x87 } +}, rtl8192eu_mac[]={ + { 0x011, 0xeb }, { 0x012, 0x07 }, { 0x014, 0x75 }, { 0x303, 0xa7 }, + { 0x421, 0x0f }, { 0x428, 0x0a }, { 0x429, 0x10 }, { 0x430, 0x00 }, + { 0x431, 0x00 }, { 0x432, 0x00 }, { 0x433, 0x01 }, { 0x434, 0x04 }, + { 0x435, 0x05 }, { 0x436, 0x07 }, { 0x437, 0x08 }, { 0x43c, 0x04 }, + { 0x43d, 0x05 }, { 0x43e, 0x07 }, { 0x43f, 0x08 }, { 0x440, 0x5d }, + { 0x441, 0x01 }, { 0x442, 0x00 }, { 0x444, 0x10 }, { 0x445, 0x00 }, + { 0x446, 0x00 }, { 0x447, 0x00 }, { 0x448, 0x00 }, { 0x449, 0xf0 }, + { 0x44a, 0x0f }, { 0x44b, 0x3e }, { 0x44c, 0x10 }, { 0x44d, 0x00 }, + { 0x44e, 0x00 }, { 0x44f, 0x00 }, { 0x450, 0x00 }, { 0x451, 0xf0 }, + { 0x452, 0x0f }, { 0x453, 0x00 }, { 0x456, 0x5e }, { 0x460, 0x66 }, + { 0x461, 0x66 }, { 0x4c8, 0xff }, { 0x4c9, 0x08 }, { 0x4cc, 0xff }, + { 0x4cd, 0xff }, { 0x4ce, 0x01 }, { 0x500, 0x26 }, { 0x501, 0xa2 }, + { 0x502, 0x2f }, { 0x503, 0x00 }, { 0x504, 0x28 }, { 0x505, 0xa3 }, + { 0x506, 0x5e }, { 0x507, 0x00 }, { 0x508, 0x2b }, { 0x509, 0xa4 }, + { 0x50a, 0x5e }, { 0x50b, 0x00 }, { 0x50c, 0x4f }, { 0x50d, 0xa4 }, + { 0x50e, 0x00 }, { 0x50f, 0x00 }, { 0x512, 0x1c }, { 0x514, 0x0a }, + { 0x516, 0x0a }, { 0x525, 0x4f }, { 0x540, 0x12 }, { 0x541, 0x64 }, + { 0x550, 0x10 }, { 0x551, 0x10 }, { 0x559, 0x02 }, { 0x55c, 0x50 }, + { 0x55d, 0xff }, { 0x605, 0x30 }, { 0x608, 0x0e }, { 0x609, 0x2a }, + { 0x620, 0xff }, { 0x621, 0xff }, { 0x622, 0xff }, { 0x623, 0xff }, + { 0x624, 0xff }, { 0x625, 0xff }, { 0x626, 0xff }, { 0x627, 0xff }, + { 0x638, 0x50 }, { 0x63c, 0x0a }, { 0x63d, 0x0a }, { 0x63e, 0x0e }, + { 0x63f, 0x0e }, { 0x640, 0x40 }, { 0x642, 0x40 }, { 0x643, 0x00 }, + { 0x652, 0x2b }, { 0x66e, 0x05 }, { 0x700, 0x21 }, { 0x701, 0x43 }, + { 0x702, 0x65 }, { 0x703, 0x87 }, { 0x708, 0x21 }, { 0x709, 0x43 }, + { 0x70a, 0x65 }, { 0x70b, 0x87 } }; /* @@ -2454,6 +2688,79 @@ static const struct r92c_rf_prog rtl8188cu_rf_prog[] = { }; /* + * RTL8192EE and RTL8192EU. + */ +static const uint8_t rtl8192e_rf_regs[] = { + 0x7f, 0x81, 0x00, 0x08, 0x18, 0x19, 0x1b, 0x1e, 0x1f, 0x2f, 0x3f, + 0x42, 0x57, 0x58, 0x67, 0x83, 0xb0, 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0x1c, 0xdf, + 0xef, 0x51, 0x52, 0x53, 0x56, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, + 0x36, 0x18, 0x5a, 0x19, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x34, 0x34, 0x00, 0x84, 0x86, 0x87, 0x8e, 0x8f, 0xef, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0xef, 0xfe, 0x18, 0xfe, 0xfe, 0xfe, + 0xfe, 0x1e, 0x1f, 0x00 +}; + +static const uint32_t rtl8192e_rf_vals[] = { + 0x00082, 0x3fc00, 0x30000, 0x08400, 0x00407, 0x00012, 0x0394c, + 0x80009, 0x00880, 0x1a060, 0x00000, 0x060c0, 0xd0000, 0xbe180, + 0x01552, 0x00000, 0xff9f1, 0x55418, 0x8cc00, 0x43083, 0x08166, + 0x0803e, 0x1c69f, 0x0407f, 0x90001, 0x40001, 0x00400, 0x00078, + 0xb3333, 0x33340, 0x00000, 0x05999, 0x09999, 0x02400, 0x00009, + 0x40c91, 0x99999, 0x000a3, 0x88820, 0x76c06, 0x00000, 0x80000, + 0x00000, 0x00180, 0x001a0, 0x69545, 0x7e45e, 0x00071, 0x51ff3, + 0x000a8, 0x001e2, 0x002a8, 0x01c24, 0x09c24, 0x11c24, 0x19c24, + 0x00c07, 0x48000, 0x739d0, 0x0add7, 0x09dd4, 0x08dd1, 0x07dce, + 0x06dcb, 0x05dc8, 0x04dc5, 0x034cc, 0x0244f, 0x0144c, 0x00014, + 0x30159, 0x68180, 0x0014e, 0x49f80, 0x65540, 0x88000, 0x020a0, + 0xf02b0, 0xef7b0, 0xd4fb0, 0xcf060, 0xb0090, 0xa0080, 0x90080, + 0x8f780, 0x78730, 0x60fb0, 0x5ffa0, 0x40620, 0x37090, 0x20080, + 0x1f060, 0x0ffb0, 0x000a0, 0x00000, 0x0fc07, 0x00000, 0x00000, + 0x00000, 0x00000, 0x00001, 0x80000, 0x33e70 +}; + +static const uint8_t rtl8192e_rf2_regs[] = { + 0x7f, 0x81, 0x00, 0x08, 0x18, 0x19, 0x1b, 0x1e, 0x1f, 0x2f, 0x3f, + 0x42, 0x57, 0x58, 0x67, 0x7f, 0x81, 0x83, 0x1c, 0xdf, 0xef, 0x51, + 0x52, 0x53, 0x56, 0x35, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x18, + 0x5a, 0x19, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x34, 0x34, 0x00, 0x84, 0x86, 0x87, 0x8e, 0x8f, 0xef, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, + 0x3b, 0x3b, 0x3b, 0xef, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x1e, 0x1f, + 0x00 +}; + +static const uint32_t rtl8192e_rf2_vals[] = { + 0x00082, 0x3fc00, 0x30000, 0x08400, 0x00407, 0x00012, 0x0394c, + 0x80009, 0x00880, 0x1a060, 0x00000, 0x060c0, 0xd0000, 0xbe180, + 0x01552, 0x00082, 0x3f000, 0x00000, 0x00000, 0x00180, 0x001a0, + 0x69545, 0x7e42e, 0x00071, 0x51ff3, 0x000a8, 0x001e0, 0x002a8, + 0x01ca8, 0x09c24, 0x11c24, 0x19c24, 0x00c07, 0x48000, 0x739d0, + 0x0add7, 0x09dd4, 0x08dd1, 0x07dce, 0x06dcb, 0x05dc8, 0x04dc5, + 0x034cc, 0x0244f, 0x0144c, 0x00014, 0x30159, 0x68180, 0x000ce, + 0x49f80, 0x65540, 0x88000, 0x020a0, 0xf02b0, 0xef7b0, 0xd4fb0, + 0xcf060, 0xb0090, 0xa0080, 0x90080, 0x8f780, 0x78730, 0x60fb0, + 0x5ffa0, 0x40620, 0x37090, 0x20080, 0x1f060, 0x0ffb0, 0x000a0, + 0x10159, 0x00000, 0x00000, 0x00000, 0x00000, 0x00001, 0x80000, + 0x33e70 +}; + +static const struct r92c_rf_prog rtl8192e_rf_prog[] = { + { + nitems(rtl8192e_rf_regs), + rtl8192e_rf_regs, + rtl8192e_rf_vals + }, + { + nitems(rtl8192e_rf2_regs), + rtl8192e_rf2_regs, + rtl8192e_rf2_vals + } +}; + +/* * RTL8188EU. */ static const uint8_t rtl8188eu_rf_regs[] = { @@ -2494,6 +2801,119 @@ static const struct r92c_rf_prog rtl8188eu_rf_prog[] = { }; /* + * RTL8192EE and RTL8192EU. + */ +static const uint16_t rtl8192e_bb_regs[] = { + 0x800, 0x804, 0x808, 0x80c, 0x810, 0x814, 0x818, 0x81c, 0x820, + 0x824, 0x828, 0x82c, 0x830, 0x834, 0x838, 0x83c, 0x840, 0x844, + 0x848, 0x84c, 0x850, 0x854, 0x858, 0x85c, 0x860, 0x864, 0x868, + 0x86c, 0x870, 0x874, 0x878, 0x87c, 0x880, 0x884, 0x888, 0x88c, + 0x890, 0x894, 0x898, 0x900, 0x904, 0x908, 0x90c, 0x910, 0x914, + 0x918, 0x91c, 0x924, 0x928, 0x92c, 0x930, 0x934, 0x938, 0x93c, + 0x940, 0x944, 0x94c, 0xa00, 0xa04, 0xa08, 0xa0c, 0xa10, 0xa14, + 0xa18, 0xa1c, 0xa20, 0xa24, 0xa28, 0xa2c, 0xa70, 0xa74, 0xa78, + 0xa7c, 0xa80, 0xb38, 0xc00, 0xc04, 0xc08, 0xc0c, 0xc10, 0xc14, + 0xc18, 0xc1c, 0xc20, 0xc24, 0xc28, 0xc2c, 0xc30, 0xc34, 0xc38, + 0xc3c, 0xc40, 0xc44, 0xc48, 0xc4c, 0xc50, 0xc54, 0xc58, 0xc5c, + 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74, 0xc78, 0xc7c, 0xc80, + 0xc84, 0xc88, 0xc8c, 0xc90, 0xc94, 0xc98, 0xc9c, 0xca0, 0xca4, + 0xca8, 0xcac, 0xcb0, 0xcb4, 0xcb8, 0xcbc, 0xcc0, 0xcc4, 0xcc8, + 0xccc, 0xcd0, 0xcd4, 0xcd8, 0xcdc, 0xce0, 0xce4, 0xce8, 0xcec, + 0xd00, 0xd04, 0xd08, 0xd0c, 0xd10, 0xd14, 0xd18, 0xd1c, 0xd2c, + 0xd30, 0xd34, 0xd38, 0xd3c, 0xd40, 0xd44, 0xd48, 0xd4c, 0xd50, + 0xd54, 0xd58, 0xd5c, 0xd60, 0xd64, 0xd68, 0xd6c, 0xd70, 0xd74, + 0xd78, 0xd80, 0xd84, 0xd88, 0xe00, 0xe04, 0xe08, 0xe10, 0xe14, + 0xe18, 0xe1c, 0xe28, 0xe30, 0xe34, 0xe38, 0xe3c, 0xe40, 0xe44, + 0xe48, 0xe4c, 0xe50, 0xe54, 0xe58, 0xe5c, 0xe60, 0xe68, 0xe6c, + 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 0xed0, + 0xed4, 0xed8, 0xedc, 0xee0, 0xeec, 0xee4, 0xee8, 0xf14, 0xf4c, + 0xf00 +}; + +static const uint32_t rtl8192e_bb_vals[] = { + 0x80040000, 0x00000003, 0x0000fc00, 0x0000000a, 0x10001331, + 0x020c3d10, 0x02220385, 0x00000000, 0x01000100, 0x00390204, + 0x01000100, 0x00390204, 0x32323232, 0x30303030, 0x30303030, + 0x30303030, 0x00010000, 0x00010000, 0x28282828, 0x28282828, + 0x00000000, 0x00000000, 0x009a009a, 0x01000014, 0x66f60000, + 0x061f0000, 0x30303030, 0x30303030, 0x00000000, 0x55004200, + 0x08080808, 0x00000000, 0xb0000c1c, 0x00000001, 0x00000000, + 0xcc0000c0, 0x00000800, 0xfffffffe, 0x40302010, 0x00000000, + 0x00000023, 0x00000000, 0x81121313, 0x806c0001, 0x00000001, + 0x00000000, 0x00010000, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000008, 0x00d0c7c8, 0x81ff800c, 0x8c838300, + 0x2e68120f, 0x95009b78, 0x1114d028, 0x00881117, 0x89140f00, + 0x1a1b0000, 0x090e1317, 0x00000204, 0x00d30000, 0x101fff80, + 0x00000007, 0x00000900, 0x225b0606, 0x218075b1, 0x00000000, + 0x48071d40, 0x03a05633, 0x000000e4, 0x6c6c6c6c, 0x08800000, + 0x40000100, 0x08800000, 0x40000100, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x69e9ac47, 0x469652af, 0x49795994, + 0x0a97971c, 0x1f7c403f, 0x000100b7, 0xec020107, 0x007f037f, + 0x00340020, 0x0080801f, 0x00000020, 0x00248492, 0x00000000, + 0x7112848b, 0x47c00bff, 0x00000036, 0x00000600, 0x02013169, + 0x0000001f, 0x00b91612, 0x40000100, 0x21f60000, 0x40000100, + 0xa0e40000, 0x00121820, 0x00000000, 0x00121820, 0x00007f7f, + 0x00000000, 0x000300a0, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x28000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x64b22427, + 0x00766932, 0x00222222, 0x00040000, 0x77644302, 0x2f97d40c, + 0x00080740, 0x00020403, 0x0000907f, 0x20010201, 0xa0633333, + 0x3333bc43, 0x7a8f5b6b, 0x0000007f, 0xcc979975, 0x00000000, + 0x80608000, 0x00000000, 0x00127353, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x6437140a, 0x00000000, 0x00000282, + 0x30032064, 0x4653de68, 0x04518a3c, 0x00002101, 0x2a201c16, + 0x1812362e, 0x322c2220, 0x000e3c24, 0x01081008, 0x00000800, + 0xf0b50000, 0x30303030, 0x30303030, 0x03903030, 0x30303030, + 0x30303030, 0x30303030, 0x30303030, 0x00000000, 0x1000dc1f, + 0x10008c1f, 0x02140102, 0x681604c2, 0x01007c00, 0x01004800, + 0xfb000000, 0x000028d1, 0x1000dc1f, 0x10008c1f, 0x02140102, + 0x28160d05, 0x00000008, 0x0fc05656, 0x03c09696, 0x03c09696, + 0x0c005656, 0x0c005656, 0x0c005656, 0x0c005656, 0x03c09696, + 0x0c005656, 0x03c09696, 0x03c09696, 0x03c09696, 0x03c09696, + 0x0000d6d6, 0x0000d6d6, 0x0fc01616, 0xb0000c1c, 0x00000001, + 0x00000003, 0x00000000, 0x00000300 +}; + +static const uint32_t rtl8192eu_agc_vals[] = { + 0xfb000001, 0xfb010001, 0xfb020001, 0xfb030001, 0xfb040001, + 0xfb050001, 0xfb060001, 0xfa070001, 0xf9080001, 0xf8090001, + 0xf70a0001, 0xf60b0001, 0xf50c0001, 0xf40d0001, 0xf30e0001, + 0xf20f0001, 0xf1100001, 0xf0110001, 0xef120001, 0xee130001, + 0xed140001, 0xec150001, 0xeb160001, 0xea170001, 0xcd180001, + 0xcc190001, 0xcb1a0001, 0xca1b0001, 0xc91c0001, 0xc81d0001, + 0x071e0001, 0x061f0001, 0x05200001, 0x04210001, 0x03220001, + 0xaa230001, 0xa9240001, 0xa8250001, 0xa7260001, 0xa6270001, + 0x85280001, 0x84290001, 0x832a0001, 0x252b0001, 0x242c0001, + 0x232d0001, 0x222e0001, 0x672f0001, 0x66300001, 0x65310001, + 0x64320001, 0x63330001, 0x62340001, 0x61350001, 0x45360001, + 0x44370001, 0x43380001, 0x42390001, 0x413a0001, 0x403b0001, + 0x403c0001, 0x403d0001, 0x403e0001, 0x403f0001, 0xfb400001, + 0xfb410001, 0xfb420001, 0xfb430001, 0xfb440001, 0xfb450001, + 0xfb460001, 0xfa470001, 0xf9480001, 0xf8490001, 0xf74a0001, + 0xf64b0001, 0xf54c0001, 0xf44d0001, 0xf34e0001, 0xf24f0001, + 0xf1500001, 0xf0510001, 0xef520001, 0xee530001, 0xed540001, + 0xec550001, 0xeb560001, 0xea570001, 0xe9580001, 0xe8590001, + 0xe75a0001, 0xe65b0001, 0xe55c0001, 0xe45d0001, 0xe35e0001, + 0xe25f0001, 0xe1600001, 0x8a610001, 0x89620001, 0x88630001, + 0x87640001, 0x86650001, 0x85660001, 0x84670001, 0x83680001, + 0x82690001, 0x6b6a0001, 0x6a6b0001, 0x696c0001, 0x686d0001, + 0x676e0001, 0x666f0001, 0x65700001, 0x64710001, 0x63720001, + 0x62730001, 0x61740001, 0x49750001, 0x48760001, 0x47770001, + 0x46780001, 0x45790001, 0x447a0001, 0x437b0001, 0x427c0001, + 0x417d0001, 0x407e0001, 0x407f0001 +}; + +static const struct r92c_bb_prog rtl8192eu_bb_prog = { + nitems(rtl8192e_bb_regs), + rtl8192e_bb_regs, + rtl8192e_bb_vals, + nitems(rtl8192eu_agc_vals), + rtl8192eu_agc_vals +}; + + +/* * RTL8188RU. */ static const uint32_t rtl8188ru_rf_vals[] = { diff --git a/sys/dev/ic/rtwn.c b/sys/dev/ic/rtwn.c index 59e2f55a564..ad1fa0b9884 100644 --- a/sys/dev/ic/rtwn.c +++ b/sys/dev/ic/rtwn.c @@ -1,8 +1,9 @@ -/* $OpenBSD: rtwn.c,v 1.41 2018/10/04 01:14:30 kevlo Exp $ */ +/* $OpenBSD: rtwn.c,v 1.42 2018/12/04 10:47:32 jmatthew Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> * Copyright (c) 2015 Stefan Sperling <stsp@openbsd.org> + * Copyright (c) 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -98,7 +99,13 @@ struct rtwn_iq_cal_regs { uint32_t gpio_muxcfg; uint32_t ofdm0_trxpathena; uint32_t ofdm0_trmuxpar; + uint32_t fpga0_rfifacesw0; uint32_t fpga0_rfifacesw1; + uint32_t fpga0_rfifaceoe0; + uint32_t fpga0_rfifaceoe1; + uint32_t config_ant_a; + uint32_t config_ant_b; + uint32_t cck0_afesetting; }; void rtwn_write_1(struct rtwn_softc *, uint16_t, uint8_t); @@ -117,6 +124,7 @@ void rtwn_efuse_switch_power(struct rtwn_softc *); int rtwn_read_chipid(struct rtwn_softc *); void rtwn_read_rom(struct rtwn_softc *); void rtwn_r92c_read_rom(struct rtwn_softc *); +void rtwn_r92e_read_rom(struct rtwn_softc *); void rtwn_r88e_read_rom(struct rtwn_softc *); void rtwn_r23a_read_rom(struct rtwn_softc *); int rtwn_media_change(struct ifnet *); @@ -151,6 +159,9 @@ void rtwn_get_txpower(struct rtwn_softc *sc, int, void rtwn_r92c_get_txpower(struct rtwn_softc *, int, struct ieee80211_channel *, struct ieee80211_channel *, uint16_t[]); +void rtwn_r92e_get_txpower(struct rtwn_softc *, int, + struct ieee80211_channel *, + struct ieee80211_channel *, uint16_t[]); void rtwn_r88e_get_txpower(struct rtwn_softc *, int, struct ieee80211_channel *, struct ieee80211_channel *, uint16_t[]); @@ -205,6 +216,9 @@ rtwn_attach(struct device *pdev, struct rtwn_softc *sc) if (sc->chip & RTWN_CHIP_92C) { sc->ntxchains = (sc->chip & RTWN_CHIP_92C_1T2R) ? 1 : 2; sc->nrxchains = 2; + } else if (sc->chip & RTWN_CHIP_92E) { + sc->ntxchains = 2; + sc->nrxchains = 2; } else { sc->ntxchains = 1; sc->nrxchains = 1; @@ -226,6 +240,7 @@ rtwn_attach(struct device *pdev, struct rtwn_softc *sc) printf("%s: MAC/BB RTL%s, RF 6052 %dT%dR, address %s\n", sc->sc_pdev->dv_xname, (sc->chip & RTWN_CHIP_92C) ? "8192CU" : + (sc->chip & RTWN_CHIP_92E) ? "8192EU" : (sc->chip & RTWN_CHIP_88E) ? "8188EU" : (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" : (sc->board_type == R92C_BOARD_TYPE_MINICARD) ? @@ -386,7 +401,7 @@ rtwn_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len) for (ntries = 0; ntries < 100; ntries++) { if (!(rtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur))) break; - DELAY(1); + DELAY(10); } if (ntries == 100) { printf("%s: could not send firmware command %d\n", @@ -401,7 +416,12 @@ rtwn_fw_cmd(struct rtwn_softc *sc, uint8_t id, const void *buf, int len) memcpy(cmd.msg, buf, len); /* Write the first word last since that will trigger the FW. */ - rtwn_write_2(sc, R92C_HMEBOX_EXT(sc->fwcur), *((uint8_t *)&cmd + 4)); + if (sc->chip & RTWN_CHIP_92E) + rtwn_write_2(sc, R88E_HMEBOX_EXT(sc->fwcur), + *((uint8_t *)&cmd + 4)); + else + rtwn_write_2(sc, R92C_HMEBOX_EXT(sc->fwcur), + *((uint8_t *)&cmd + 4)); rtwn_write_4(sc, R92C_HMEBOX(sc->fwcur), *((uint8_t *)&cmd + 0)); sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX; @@ -419,13 +439,25 @@ rtwn_rf_write(struct rtwn_softc *sc, int chain, uint8_t addr, uint32_t val) { uint32_t param_addr; - if (sc->chip & RTWN_CHIP_88E) + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_4(sc, R92C_FPGA0_POWER_SAVE, + rtwn_read_4(sc, R92C_FPGA0_POWER_SAVE) & ~0x20000); + } + + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) param_addr = SM(R88E_LSSI_PARAM_ADDR, addr); else param_addr = SM(R92C_LSSI_PARAM_ADDR, addr); rtwn_bb_write(sc, R92C_LSSI_PARAM(chain), param_addr | SM(R92C_LSSI_PARAM_DATA, val)); + + DELAY(1); + + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_4(sc, R92C_FPGA0_POWER_SAVE, + rtwn_read_4(sc, R92C_FPGA0_POWER_SAVE) | 0x20000); + } } uint32_t @@ -571,7 +603,7 @@ rtwn_read_chipid(struct rtwn_softc *sc) { uint32_t reg; - if (sc->chip & RTWN_CHIP_88E) { + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) { sc->sc_flags |= RTWN_FLAG_EXT_HDR; return (0); } @@ -615,6 +647,8 @@ rtwn_read_rom(struct rtwn_softc *sc) { if (sc->chip & RTWN_CHIP_88E) rtwn_r88e_read_rom(sc); + else if (sc->chip & RTWN_CHIP_92E) + rtwn_r92e_read_rom(sc); else if (sc->chip & RTWN_CHIP_23A) rtwn_r23a_read_rom(sc); else @@ -645,6 +679,25 @@ rtwn_r92c_read_rom(struct rtwn_softc *sc) } void +rtwn_r92e_read_rom(struct rtwn_softc *sc) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct r92e_rom *rom = &sc->sc_r92e_rom; + + /* Read full ROM image. */ + rtwn_efuse_read(sc, (uint8_t *)&sc->sc_r92e_rom, + sizeof(sc->sc_r92e_rom)); + + sc->crystal_cap = rom->xtal_k; + 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)); + + IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr); +} + +void rtwn_r88e_read_rom(struct rtwn_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -749,7 +802,7 @@ rtwn_ra_init(struct rtwn_softc *sc) rtwn_write_4(sc, R92C_ARFR(0), rates & 0x07f5); } - if (sc->chip & RTWN_CHIP_88E) { + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) { error = rtwn_r88e_ra_init(sc, mode, rates, maxrate, basicrates, maxbasicrate); /* We use AMRR with this chip. Start with the lowest rate. */ @@ -875,7 +928,17 @@ rtwn_set_led(struct rtwn_softc *sc, int led, int on) reg |= R92C_LEDCFG2_EN; rtwn_write_1(sc, R92C_LEDCFG2, reg); } else if (sc->chip & RTWN_CHIP_USB) { - if (sc->chip & RTWN_CHIP_88E) { + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_1(sc, 0x64, rtwn_read_1(sc, 0x64) & 0xfe); + reg = rtwn_read_1(sc, R92C_LEDCFG1) & R92E_LEDSON; + rtwn_write_1(sc, R92C_LEDCFG1, reg | + (R92C_LEDCFG0_DIS << 1)); + if (on) { + reg = rtwn_read_1(sc, R92C_LEDCFG1) & + R92E_LEDSON; + rtwn_write_1(sc, R92C_LEDCFG1, reg); + } + } else if (sc->chip & RTWN_CHIP_88E) { reg = rtwn_read_1(sc, R92C_LEDCFG2) & 0xf0; rtwn_write_1(sc, R92C_LEDCFG2, reg | R92C_LEDCFG2_EN); if (!on) { @@ -920,15 +983,28 @@ rtwn_set_nettype(struct rtwn_softc *sc, enum ieee80211_opmode opmode) void rtwn_calib(struct rtwn_softc *sc) { - struct r92c_fw_cmd_rssi cmd; if (sc->avg_pwdb != -1) { - /* Indicate Rx signal strength to FW for rate adaptation. */ - memset(&cmd, 0, sizeof(cmd)); - cmd.macid = 0; /* BSS. */ - cmd.pwdb = sc->avg_pwdb; DPRINTFN(3, ("sending RSSI command avg=%d\n", sc->avg_pwdb)); - rtwn_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, sizeof(cmd)); + + /* Indicate Rx signal strength to FW for rate adaptation. */ + if (sc->chip & RTWN_CHIP_92E) { + struct r92e_fw_cmd_rssi cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.macid = 0; /* BSS. */ + cmd.pwdb = sc->avg_pwdb; + rtwn_fw_cmd(sc, R92E_CMD_RSSI_REPORT, &cmd, + sizeof(cmd)); + } else { + struct r92c_fw_cmd_rssi cmd; + + memset(&cmd, 0, sizeof(cmd)); + cmd.macid = 0; /* BSS. */ + cmd.pwdb = sc->avg_pwdb; + rtwn_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, + sizeof(cmd)); + } } /* Do temperature compensation. */ @@ -1120,7 +1196,7 @@ rtwn_update_short_preamble(struct ieee80211com *ic) { struct rtwn_softc *sc = ic->ic_softc; - if (sc->chip & RTWN_CHIP_88E) + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) rtwn_r88e_update_short_preamble(sc); else rtwn_r92c_update_short_preamble(sc); @@ -1345,7 +1421,7 @@ rtwn_get_rssi(struct rtwn_softc *sc, int rate, void *physt) uint8_t rpt; int8_t rssi; - if (sc->chip & RTWN_CHIP_88E) + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) return rtwn_r88e_get_rssi(sc, rate, physt); if (rate <= 3) { @@ -1524,7 +1600,7 @@ rtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) void rtwn_fw_reset(struct rtwn_softc *sc) { - if (sc->chip & RTWN_CHIP_88E) + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) rtwn_r88e_fw_reset(sc); else rtwn_r92c_fw_reset(sc); @@ -1564,13 +1640,14 @@ rtwn_r88e_fw_reset(struct rtwn_softc *sc) uint16_t reg; /* Reset MCU IO wrapper. */ - rtwn_write_1(sc, R92C_RSV_CTRL + 1, - rtwn_read_1(sc, R92C_RSV_CTRL + 1) & ~R92C_RSV_CTRL_WLOCK_08); + rtwn_write_2(sc, R92C_RSV_CTRL, + rtwn_read_2(sc, R92C_RSV_CTRL) & ~R88E_RSV_CTRL_MIO_EN); reg = rtwn_read_2(sc, R92C_SYS_FUNC_EN); rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN); + /* Enable MCU IO wrapper. */ - rtwn_write_1(sc, R92C_RSV_CTRL + 1, - rtwn_read_1(sc, R92C_RSV_CTRL) | R92C_RSV_CTRL_WLOCK_08); + rtwn_write_2(sc, R92C_RSV_CTRL, + rtwn_read_2(sc, R92C_RSV_CTRL) | R88E_RSV_CTRL_MIO_EN); rtwn_write_2(sc, R92C_SYS_FUNC_EN, reg | R92C_SYS_FUNC_EN_CPUEN); } @@ -1599,7 +1676,8 @@ rtwn_load_firmware(struct rtwn_softc *sc) if ((letoh16(hdr->signature) >> 4) == 0x230 || (letoh16(hdr->signature) >> 4) == 0x88c || (letoh16(hdr->signature) >> 4) == 0x88e || - (letoh16(hdr->signature) >> 4) == 0x92c) { + (letoh16(hdr->signature) >> 4) == 0x92c || + (letoh16(hdr->signature) >> 4) == 0x92e) { DPRINTF(("FW V%d.%d %02d-%02d %02d:%02d\n", letoh16(hdr->version), letoh16(hdr->subversion), hdr->month, hdr->date, hdr->hour, hdr->minute)); @@ -1627,6 +1705,7 @@ rtwn_load_firmware(struct rtwn_softc *sc) rtwn_write_1(sc, R92C_MCUFWDL, rtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_CHKSUM_RPT); + DELAY(50); for (page = 0; len > 0; page++) { mlen = MIN(len, R92C_FW_PAGE_SIZE); error = sc->sc_ops.fw_loadpage(sc->sc_ops.cookie, page, ptr, @@ -1696,6 +1775,8 @@ rtwn_rf_init(struct rtwn_softc *sc) /* Select RF programming based on board type. */ if (sc->chip & RTWN_CHIP_88E) prog = rtl8188eu_rf_prog; + else if (sc->chip & RTWN_CHIP_92E) + prog = rtl8192e_rf_prog; else if (!(sc->chip & RTWN_CHIP_92C)) { if (sc->board_type == R92C_BOARD_TYPE_MINICARD) prog = rtl8188ce_rf_prog; @@ -1717,36 +1798,47 @@ rtwn_rf_init(struct rtwn_softc *sc) reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i)); reg |= 0x100000; rtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg); - DELAY(1); + DELAY(50); /* Set RF_ENV output high. */ reg = rtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i)); reg |= 0x10; rtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg); - DELAY(1); + DELAY(50); /* Set address and data lengths of RF registers. */ reg = rtwn_bb_read(sc, R92C_HSSI_PARAM2(i)); reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH; rtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg); - DELAY(1); + DELAY(50); reg = rtwn_bb_read(sc, R92C_HSSI_PARAM2(i)); reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH; rtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg); - DELAY(1); + DELAY(50); /* Write RF initialization values for this chain. */ for (j = 0; j < prog[i].count; j++) { - if (prog[i].regs[j] >= 0xf9 && - prog[i].regs[j] <= 0xfe) { - /* - * These are fake RF registers offsets that - * indicate a delay is required. - */ + switch (prog[i].regs[j]) { + case 0xfe: + DELAY(50000); + continue; + case 0xfd: + DELAY(5000); + continue; + case 0xfc: + DELAY(1000); + continue; + case 0xfb: DELAY(50); continue; + case 0xfa: + DELAY(5); + continue; + case 0xf9: + DELAY(1); + continue; } rtwn_rf_write(sc, i, prog[i].regs[j], prog[i].vals[j]); - DELAY(1); + DELAY(5); } /* Restore RF_ENV control type. */ @@ -1863,7 +1955,7 @@ rtwn_edca_init(struct rtwn_softc *sc) void rtwn_rate_fallback_init(struct rtwn_softc *sc) { - if (!(sc->chip & RTWN_CHIP_88E)) { + if (!(sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E))) { if (sc->chip & RTWN_CHIP_PCI) { rtwn_write_4(sc, R92C_DARFRC + 0, 0x01000000); rtwn_write_4(sc, R92C_DARFRC + 4, 0x07060504); @@ -1884,19 +1976,34 @@ rtwn_usb_aggr_init(struct rtwn_softc *sc) uint32_t reg; int dmasize, dmatiming, ndesc; - dmasize = 48; - dmatiming = 4; - ndesc = (sc->chip & RTWN_CHIP_88E) ? 1 : 6; + if (sc->chip & RTWN_CHIP_92E) { + dmasize = 0x06; + dmatiming = 0x20; + ndesc = 3; + } else { + dmasize = 48; + dmatiming = 4; + ndesc = (sc->chip & RTWN_CHIP_88E) ? 1 : 6; + } /* Tx aggregation setting. */ - reg = rtwn_read_4(sc, R92C_TDECTRL); - reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, ndesc); - rtwn_write_4(sc, R92C_TDECTRL, reg); + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_1(sc, R92E_DWBCN1_CTRL, ndesc << 1); + } else { + reg = rtwn_read_4(sc, R92C_TDECTRL); + reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, ndesc); + rtwn_write_4(sc, R92C_TDECTRL, reg); + } /* Rx aggregation setting. */ - rtwn_write_1(sc, R92C_TRXDMA_CTRL, - rtwn_read_1(sc, R92C_TRXDMA_CTRL) | - R92C_TRXDMA_CTRL_RXDMA_AGG_EN); + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_1(sc, R92E_RXDMA_PRO, + (rtwn_read_1(sc, R92E_RXDMA_PRO) & ~0x20) | 0x1e); + } else { + rtwn_write_1(sc, R92C_TRXDMA_CTRL, + rtwn_read_1(sc, R92C_TRXDMA_CTRL) | + R92C_TRXDMA_CTRL_RXDMA_AGG_EN); + } rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, dmasize); if (sc->chip & (RTWN_CHIP_92C | RTWN_CHIP_88C)) rtwn_write_1(sc, R92C_USB_DMA_AGG_TO, dmatiming); @@ -1972,6 +2079,8 @@ rtwn_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, { if (sc->chip & RTWN_CHIP_88E) rtwn_r88e_get_txpower(sc, chain, c, extc, power); + else if (sc->chip & RTWN_CHIP_92E) + rtwn_r92e_get_txpower(sc, chain, c, extc, power); else rtwn_r92c_get_txpower(sc, chain, c, extc, power); } @@ -2076,6 +2185,68 @@ rtwn_r92c_get_txpower(struct rtwn_softc *sc, int chain, } void +rtwn_r92e_get_txpower(struct rtwn_softc *sc, int chain, + struct ieee80211_channel *c, struct ieee80211_channel *extc, + uint16_t power[RTWN_POWER_COUNT]) +{ + struct ieee80211com *ic = &sc->sc_ic; + struct r92e_rom *rom = &sc->sc_r92e_rom; + struct r92e_tx_pwr *txpwr; + uint8_t cckpow, ofdmpow; + int8_t diff; + int ridx, chan, group; + + /* Determine channel group. */ + chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */ + if (chan <= 2) + group = 0; + else if (chan <= 5) + group = 1; + else if (chan <= 8) + group = 2; + else if (chan <= 11) + group = 3; + else + group = 4; + + memset(power, 0, RTWN_POWER_COUNT * sizeof(power[0])); + + if (chain == 0) + txpwr = &rom->txpwr_a; + else + txpwr = &rom->txpwr_b; + + /* Compute per-CCK rate Tx power. */ + cckpow = txpwr->cck_tx_pwr[group]; + 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; + } + + /* Compute per-OFDM rate Tx power. */ + diff = RTWN_SIGN4TO8(MS(txpwr->ht20_ofdm_tx_pwr_diff, + R92E_ROM_TXPWR_OFDM_DIFF)); + ofdmpow = txpwr->ht40_tx_pwr[group] + 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; + } + + /* Compute per-MCS Tx power. */ /* XXX apparently need to handle tx chains here? */ + if (extc == NULL) + diff = RTWN_SIGN4TO8(MS(txpwr->ht20_ofdm_tx_pwr_diff, + R92E_ROM_TXPWR_HT20_DIFF)); + + for (ridx = RTWN_RIDX_MCS0; ridx < RTWN_RIDX_MCS8; ridx++) { + power[ridx] = txpwr->ht40_tx_pwr[group] + diff; + if (power[ridx] > R92C_MAX_TX_PWR) + power[ridx] = R92C_MAX_TX_PWR; + } +} + +void rtwn_r88e_get_txpower(struct rtwn_softc *sc, int chain, struct ieee80211_channel *c, struct ieee80211_channel *extc, uint16_t power[RTWN_POWER_COUNT]) @@ -2158,6 +2329,7 @@ rtwn_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c, { struct ieee80211com *ic = &sc->sc_ic; u_int chan; + uint32_t reg; int i; chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */ @@ -2165,18 +2337,24 @@ rtwn_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c, /* Set Tx power for this new channel. */ rtwn_set_txpower(sc, c, extc); - for (i = 0; i < sc->nrxchains; i++) { - rtwn_rf_write(sc, i, R92C_RF_CHNLBW, - RW(sc->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan)); - } if (extc != NULL) { uint32_t reg; /* Is secondary channel below or above primary? */ int prichlo = c->ic_freq < extc->ic_freq; - rtwn_write_1(sc, R92C_BWOPMODE, - rtwn_read_1(sc, R92C_BWOPMODE) & ~R92C_BWOPMODE_20MHZ); + if (sc->chip & RTWN_CHIP_92E) { + uint16_t reg; + reg = rtwn_read_2(sc, R92C_WMAC_TRXPTCL_CTL); + reg &= ~R92C_WMAC_TRXPTCL_CTL_BW_MASK; + reg |= R92C_WMAC_TRXPTCL_CTL_BW_40; + rtwn_write_2(sc, R92C_WMAC_TRXPTCL_CTL, reg); + rtwn_write_1(sc, R92E_DATA_SC, 0); + } else { + rtwn_write_1(sc, R92C_BWOPMODE, + rtwn_read_1(sc, R92C_BWOPMODE) & + ~R92C_BWOPMODE_20MHZ); + } reg = rtwn_read_1(sc, R92C_RRSR + 2); reg = (reg & ~0x6f) | (prichlo ? 1 : 2) << 5; @@ -2196,7 +2374,7 @@ rtwn_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c, reg = (reg & ~0x00000c00) | (prichlo ? 1 : 2) << 10; rtwn_bb_write(sc, R92C_OFDM1_LSTF, reg); - if (!(sc->chip & RTWN_CHIP_88E)) { + if (!(sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E))) { rtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2, rtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) & ~R92C_FPGA0_ANAPARAM2_CBW20); @@ -2207,28 +2385,45 @@ rtwn_set_chan(struct rtwn_softc *sc, struct ieee80211_channel *c, rtwn_bb_write(sc, 0x818, reg); /* Select 40MHz bandwidth. */ - rtwn_rf_write(sc, 0, R92C_RF_CHNLBW, - (sc->rf_chnlbw[0] & ~0xfff) | chan); + for (i = 0; i < sc->nrxchains; i++) { + rtwn_rf_write(sc, i, R92C_RF_CHNLBW, + (sc->rf_chnlbw[i] & ~0xfff) | chan); + } } else { - rtwn_write_1(sc, R92C_BWOPMODE, - rtwn_read_1(sc, R92C_BWOPMODE) | R92C_BWOPMODE_20MHZ); + if (sc->chip & RTWN_CHIP_92E) { + uint16_t reg; + reg = rtwn_read_2(sc, R92C_WMAC_TRXPTCL_CTL); + reg &= ~R92C_WMAC_TRXPTCL_CTL_BW_MASK; + rtwn_write_2(sc, R92C_WMAC_TRXPTCL_CTL, reg); + rtwn_write_1(sc, R92E_DATA_SC, 0); + } else { + rtwn_write_1(sc, R92C_BWOPMODE, + rtwn_read_1(sc, R92C_BWOPMODE) | + R92C_BWOPMODE_20MHZ); + } rtwn_bb_write(sc, R92C_FPGA0_RFMOD, rtwn_bb_read(sc, R92C_FPGA0_RFMOD) & ~R92C_RFMOD_40MHZ); rtwn_bb_write(sc, R92C_FPGA1_RFMOD, rtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ); - if (!(sc->chip & RTWN_CHIP_88E)) { + if (!(sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E))) { rtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2, rtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) | R92C_FPGA0_ANAPARAM2_CBW20); + } else if (sc->chip & RTWN_CHIP_92E) { + reg = rtwn_read_4(sc, R92C_OFDM0_TX_PSDO_NOISE_WEIGHT); + reg &= ~0xc0000000; + rtwn_write_4(sc, R92C_OFDM0_TX_PSDO_NOISE_WEIGHT, reg); } /* Select 20MHz bandwidth. */ - rtwn_rf_write(sc, 0, R92C_RF_CHNLBW, - (sc->rf_chnlbw[0] & ~0xfff) | chan | - ((sc->chip & RTWN_CHIP_88E) ? R88E_RF_CHNLBW_BW20 : - R92C_RF_CHNLBW_BW20)); + for (i = 0; i < sc->nrxchains; i++) { + rtwn_rf_write(sc, i, R92C_RF_CHNLBW, + (sc->rf_chnlbw[i] & ~0xfff) | chan | + ((sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) ? + R88E_RF_CHNLBW_BW20 : R92C_RF_CHNLBW_BW20)); + } } if (sc->chip == (RTWN_CHIP_88E | RTWN_CHIP_PCI)) @@ -2241,33 +2436,48 @@ rtwn_iq_calib_chain(struct rtwn_softc *sc, int chain, uint16_t tx[2], { uint32_t status; int offset = chain * 0x20; + uint32_t iqk_tone_92c[] = { + 0x10008c1f, 0x10008c1f, 0x82140102, 0x28160202, 0x10008c22 + }; + uint32_t iqk_tone_92e[] = { + 0x18008c1c, 0x38008c1c, 0x82140303, 0x68160000, 0x38008c1c + }; + uint32_t *iqk_tone; + + if (sc->chip & RTWN_CHIP_92E) + iqk_tone = iqk_tone_92e; + else + iqk_tone = iqk_tone_92c; if (chain == 0) { /* IQ calibration for chain 0. */ /* IQ calibration settings for chain 0. */ - rtwn_bb_write(sc, 0xe30, 0x10008c1f); - rtwn_bb_write(sc, 0xe34, 0x10008c1f); - rtwn_bb_write(sc, 0xe38, 0x82140102); + rtwn_bb_write(sc, R92C_TX_IQK_TONE_A, iqk_tone[0]); + rtwn_bb_write(sc, R92C_RX_IQK_TONE_B, iqk_tone[1]); + rtwn_bb_write(sc, R92C_TX_IQK_PI_A, iqk_tone[2]); if (sc->ntxchains > 1) { - rtwn_bb_write(sc, 0xe3c, 0x28160202); /* 2T */ + rtwn_bb_write(sc, R92C_RX_IQK_PI_A, iqk_tone[3]); /* IQ calibration settings for chain 1. */ - rtwn_bb_write(sc, 0xe50, 0x10008c22); - rtwn_bb_write(sc, 0xe54, 0x10008c22); - rtwn_bb_write(sc, 0xe58, 0x82140102); - rtwn_bb_write(sc, 0xe5c, 0x28160202); + rtwn_bb_write(sc, R92C_TX_IQK_TONE_B, iqk_tone[4]); + rtwn_bb_write(sc, R92C_RX_IQK_TONE_B, iqk_tone[4]); + rtwn_bb_write(sc, R92C_TX_IQK_PI_B, 0x82140102); + rtwn_bb_write(sc, R92C_RX_IQK_PI_B, 0x28160202); } else - rtwn_bb_write(sc, 0xe3c, 0x28160502); /* 1T */ + rtwn_bb_write(sc, R92C_RX_IQK_PI_A, 0x28160502); /* LO calibration settings. */ - rtwn_bb_write(sc, 0xe4c, 0x001028d1); + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) + rtwn_bb_write(sc, R92C_IQK_AGC_RSP, 0x00462911); + else + rtwn_bb_write(sc, R92C_IQK_AGC_RSP, 0x001028d1); /* We're doing LO and IQ calibration in one shot. */ - rtwn_bb_write(sc, 0xe48, 0xf9000000); - rtwn_bb_write(sc, 0xe48, 0xf8000000); + rtwn_bb_write(sc, R92C_IQK_AGC_PTS, 0xf9000000); + rtwn_bb_write(sc, R92C_IQK_AGC_PTS, 0xf8000000); } else { /* IQ calibration for chain 1. */ /* We're doing LO and IQ calibration in one shot. */ - rtwn_bb_write(sc, 0xe60, 0x00000002); - rtwn_bb_write(sc, 0xe60, 0x00000000); + rtwn_bb_write(sc, R92C_IQK_AGC_CONT, 0x00000002); + rtwn_bb_write(sc, R92C_IQK_AGC_CONT, 0x00000000); } /* Give LO and IQ calibrations the time to complete. */ @@ -2279,16 +2489,20 @@ rtwn_iq_calib_chain(struct rtwn_softc *sc, int chain, uint16_t tx[2], if (status & (1 << (28 + chain * 3))) return (0); /* Tx failed. */ /* Read Tx IQ calibration results. */ - tx[0] = (rtwn_bb_read(sc, 0xe94 + offset) >> 16) & 0x3ff; - tx[1] = (rtwn_bb_read(sc, 0xe9c + offset) >> 16) & 0x3ff; + tx[0] = (rtwn_bb_read(sc, R92C_TX_POWER_BEFORE_IQK_A + offset) >> 16) + & 0x3ff; + tx[1] = (rtwn_bb_read(sc, R92C_TX_POWER_AFTER_IQK_A + offset) >> 16) + & 0x3ff; if (tx[0] == 0x142 || tx[1] == 0x042) return (0); /* Tx failed. */ if (status & (1 << (27 + chain * 3))) return (1); /* Rx failed. */ /* Read Rx IQ calibration results. */ - rx[0] = (rtwn_bb_read(sc, 0xea4 + offset) >> 16) & 0x3ff; - rx[1] = (rtwn_bb_read(sc, 0xeac + offset) >> 16) & 0x3ff; + rx[0] = (rtwn_bb_read(sc, R92C_RX_POWER_BEFORE_IQK_A_2 + offset) >> 16) + & 0x3ff; + rx[1] = (rtwn_bb_read(sc, R92C_RX_POWER_AFTER_IQK_A_2 + offset) >> 16) + & 0x3ff; if (rx[0] == 0x132 || rx[1] == 0x036) return (1); /* Rx failed. */ @@ -2305,8 +2519,25 @@ rtwn_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2], 0xe88, 0xe8c, 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 0xeec }; + static const uint32_t adda_92c[] = { + 0x0b1b25a0, 0x0bdb25a0, 0x04db25a4, 0x0b1b25a4 + }; + static const uint32_t adda_92e[] = { + 0x0fc01616, 0x0fc01616, 0x0fc01616, 0x0fc01616 + }; + const uint32_t *adda_vals; + int i, chain; - uint32_t hssi_param1; + uint32_t hssi_param1, reg; + uint8_t xa_agc, xb_agc; + + xa_agc = rtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0)) & 0xff; + xb_agc = rtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1)) & 0xff; + + if (sc->chip & RTWN_CHIP_92E) + adda_vals = adda_92e; + else + adda_vals = adda_92c; if (n == 0) { for (i = 0; i < nitems(reg_adda); i++) @@ -2319,20 +2550,12 @@ rtwn_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2], } if (sc->ntxchains == 1) { - rtwn_bb_write(sc, reg_adda[0], 0x0b1b25a0); + rtwn_bb_write(sc, reg_adda[0], adda_vals[0]); for (i = 1; i < nitems(reg_adda); i++) - rtwn_bb_write(sc, reg_adda[i], 0x0bdb25a0); + rtwn_bb_write(sc, reg_adda[i], adda_vals[1]); } else { for (i = 0; i < nitems(reg_adda); i++) - rtwn_bb_write(sc, reg_adda[i], 0x04db25a4); - } - - hssi_param1 = rtwn_bb_read(sc, R92C_HSSI_PARAM1(0)); - if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) { - rtwn_bb_write(sc, R92C_HSSI_PARAM1(0), - hssi_param1 | R92C_HSSI_PARAM1_PI); - rtwn_bb_write(sc, R92C_HSSI_PARAM1(1), - hssi_param1 | R92C_HSSI_PARAM1_PI); + rtwn_bb_write(sc, reg_adda[i], adda_vals[2]); } if (n == 0) { @@ -2340,21 +2563,61 @@ rtwn_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2], rtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA); iq_cal_regs->ofdm0_trmuxpar = rtwn_bb_read(sc, R92C_OFDM0_TRMUXPAR); + iq_cal_regs->fpga0_rfifacesw0 = + rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(0)); iq_cal_regs->fpga0_rfifacesw1 = rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(1)); + iq_cal_regs->fpga0_rfifaceoe0 = + rtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(0)); + iq_cal_regs->fpga0_rfifaceoe1 = + rtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(1)); + iq_cal_regs->config_ant_a = + rtwn_bb_read(sc, R92C_CONFIG_ANT_A); + iq_cal_regs->config_ant_b = + rtwn_bb_read(sc, R92C_CONFIG_ANT_B); + iq_cal_regs->cck0_afesetting = + rtwn_bb_read(sc, R92C_CCK0_AFESETTING); + } + + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_4(sc, R92C_CCK0_AFESETTING, rtwn_read_4(sc, + R92C_CCK0_AFESETTING) | 0x0f000000); + } else { + hssi_param1 = rtwn_bb_read(sc, R92C_HSSI_PARAM1(0)); + if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) { + rtwn_bb_write(sc, R92C_HSSI_PARAM1(0), + hssi_param1 | R92C_HSSI_PARAM1_PI); + rtwn_bb_write(sc, R92C_HSSI_PARAM1(1), + hssi_param1 | R92C_HSSI_PARAM1_PI); + } } rtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, 0x03a05600); rtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, 0x000800e4); - rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), 0x22204000); - if (sc->ntxchains > 1) { - rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00010000); - rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00010000); - } - rtwn_write_1(sc, R92C_TXPAUSE, R92C_TXPAUSE_AC_VO | - R92C_TXPAUSE_AC_VI | R92C_TXPAUSE_AC_BE | R92C_TXPAUSE_AC_BK | - R92C_TXPAUSE_MGNT | R92C_TXPAUSE_HIGH); + if (sc->chip & RTWN_CHIP_92E) { + rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), 0x22208200); + rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(0), + rtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(0)) | (1 << 10) | + (1 << 26)); + + rtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(0), rtwn_bb_read(sc, + R92C_FPGA0_RFIFACEOE(0)) | (1 << 10)); + rtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(1), rtwn_bb_read(sc, + R92C_FPGA0_RFIFACEOE(1)) | (1 << 10)); + } else { + rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), 0x22204000); + + if (sc->ntxchains > 1) { + rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00010000); + rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00010000); + } + + rtwn_write_1(sc, R92C_TXPAUSE, R92C_TXPAUSE_AC_VO | + R92C_TXPAUSE_AC_VI | R92C_TXPAUSE_AC_BE | + R92C_TXPAUSE_AC_BK | R92C_TXPAUSE_MGNT | + R92C_TXPAUSE_HIGH); + } rtwn_write_1(sc, R92C_BCN_CTRL, iq_cal_regs->bcn_ctrl & ~(R92C_BCN_CTRL_EN_BCN)); rtwn_write_1(sc, R92C_BCN_CTRL1, @@ -2362,26 +2625,26 @@ rtwn_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2], rtwn_write_1(sc, R92C_GPIO_MUXCFG, iq_cal_regs->gpio_muxcfg & ~(R92C_GPIO_MUXCFG_ENBT)); - rtwn_bb_write(sc, 0x0b68, 0x00080000); + rtwn_bb_write(sc, R92C_CONFIG_ANT_A, 0x00080000); if (sc->ntxchains > 1) - rtwn_bb_write(sc, 0x0b6c, 0x00080000); + rtwn_bb_write(sc, R92C_CONFIG_ANT_B, 0x00080000); - rtwn_bb_write(sc, 0x0e28, 0x80800000); - rtwn_bb_write(sc, 0x0e40, 0x01007c00); - rtwn_bb_write(sc, 0x0e44, 0x01004800); + rtwn_bb_write(sc, R92C_FPGA0_IQK, 0x80800000); + rtwn_bb_write(sc, R92C_TX_IQK, 0x01007c00); + rtwn_bb_write(sc, R92C_RX_IQK, 0x01004800); - rtwn_bb_write(sc, 0x0b68, 0x00080000); + rtwn_bb_write(sc, R92C_CONFIG_ANT_A, 0x00080000); for (chain = 0; chain < sc->ntxchains; chain++) { if (chain > 0) { /* Put chain 0 on standby. */ - rtwn_bb_write(sc, 0x0e28, 0x00); + rtwn_bb_write(sc, R92C_FPGA0_IQK, 0x00); rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00010000); - rtwn_bb_write(sc, 0x0e28, 0x80800000); + rtwn_bb_write(sc, R92C_FPGA0_IQK, 0x80800000); /* Enable chain 1. */ for (i = 0; i < nitems(reg_adda); i++) - rtwn_bb_write(sc, reg_adda[i], 0x0b1b25a4); + rtwn_bb_write(sc, reg_adda[i], adda_vals[3]); } /* Run IQ calibration twice. */ @@ -2413,21 +2676,22 @@ rtwn_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2], tx[chain][0], tx[chain][1], rx[chain][0], rx[chain][1])); } - rtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, - iq_cal_regs->ofdm0_trxpathena); - rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), - iq_cal_regs->fpga0_rfifacesw1); - rtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, iq_cal_regs->ofdm0_trmuxpar); + rtwn_bb_write(sc, R92C_FPGA0_IQK, 0x00); - rtwn_bb_write(sc, 0x0e28, 0x00); - rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00032ed3); - if (sc->ntxchains > 1) - rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00032ed3); + if (!(sc->chip & RTWN_CHIP_92E)) { + rtwn_bb_write(sc, R92C_LSSI_PARAM(0), 0x00032ed3); + if (sc->ntxchains > 1) + rtwn_bb_write(sc, R92C_LSSI_PARAM(1), 0x00032ed3); + } if (n != 0) { - if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) { - rtwn_bb_write(sc, R92C_HSSI_PARAM1(0), hssi_param1); - rtwn_bb_write(sc, R92C_HSSI_PARAM1(1), hssi_param1); + if (!(sc->chip & RTWN_CHIP_92E)) { + if (!(hssi_param1 & R92C_HSSI_PARAM1_PI)) { + rtwn_bb_write(sc, R92C_HSSI_PARAM1(0), + hssi_param1); + rtwn_bb_write(sc, R92C_HSSI_PARAM1(1), + hssi_param1); + } } for (i = 0; i < nitems(reg_adda); i++) @@ -2437,6 +2701,38 @@ rtwn_iq_calib_run(struct rtwn_softc *sc, int n, uint16_t tx[2][2], rtwn_write_1(sc, R92C_BCN_CTRL, iq_cal_regs->bcn_ctrl); rtwn_write_1(sc, R92C_BCN_CTRL1, iq_cal_regs->bcn_ctrl1); rtwn_write_4(sc, R92C_GPIO_MUXCFG, iq_cal_regs->gpio_muxcfg); + + rtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, + iq_cal_regs->ofdm0_trxpathena); + rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(0), + iq_cal_regs->fpga0_rfifacesw0); + rtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(1), + iq_cal_regs->fpga0_rfifacesw1); + rtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(0), + iq_cal_regs->fpga0_rfifaceoe0); + rtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(1), + iq_cal_regs->fpga0_rfifaceoe1); + rtwn_bb_write(sc, R92C_OFDM0_TRMUXPAR, + iq_cal_regs->ofdm0_trmuxpar); + rtwn_bb_write(sc, R92C_CONFIG_ANT_A, + iq_cal_regs->config_ant_a); + rtwn_bb_write(sc, R92C_CONFIG_ANT_B, + iq_cal_regs->config_ant_b); + rtwn_bb_write(sc, R92C_CCK0_AFESETTING, + iq_cal_regs->cck0_afesetting); + + reg = rtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0)); + reg &= ~0xff; + rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg | 0x50); + rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg | xa_agc); + + reg = rtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1)); + reg &= ~0xff; + rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg | 0x50); + rtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg | xb_agc); + + rtwn_bb_write(sc, R92C_TX_IQK_TONE_A, 0x01008c00); + rtwn_bb_write(sc, R92C_RX_IQK_TONE_A, 0x01008c00); } } @@ -2618,18 +2914,26 @@ rtwn_lc_calib(struct rtwn_softc *sc) void rtwn_temp_calib(struct rtwn_softc *sc) { - int temp; + int temp, t_meter_reg, t_meter_val; + + if (sc->chip & RTWN_CHIP_92E) { + t_meter_reg = R92E_RF_T_METER; + t_meter_val = 0x37cf8; + } else { + t_meter_reg = R92C_RF_T_METER; + t_meter_val = 0x60; + } if (sc->thcal_state == 0) { /* Start measuring temperature. */ - rtwn_rf_write(sc, 0, R92C_RF_T_METER, 0x60); + rtwn_rf_write(sc, 0, t_meter_reg, t_meter_val); sc->thcal_state = 1; return; } sc->thcal_state = 0; /* Read measured temperature. */ - temp = rtwn_rf_read(sc, 0, R92C_RF_T_METER) & 0x1f; + temp = rtwn_rf_read(sc, 0, t_meter_reg) & 0x1f; if (temp == 0) /* Read failed, skip. */ return; DPRINTFN(2, ("temperature=%d\n", temp)); @@ -2654,7 +2958,10 @@ rtwn_temp_calib(struct rtwn_softc *sc) void rtwn_enable_intr(struct rtwn_softc *sc) { - if (sc->chip & RTWN_CHIP_88E) { + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_4(sc, R88E_HIMR, 0); + rtwn_write_4(sc, R88E_HIMRE, 0); + } else if (sc->chip & RTWN_CHIP_88E) { rtwn_write_4(sc, R88E_HISR, 0xffffffff); if (sc->chip & RTWN_CHIP_USB) { rtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | @@ -2813,7 +3120,7 @@ rtwn_init(struct ifnet *ifp) rtwn_write_1(sc, R92C_BCNDMATIM, R92C_BCNDMATIM_INIT_TIME); rtwn_write_2(sc, R92C_BCNTCFG, 0x660f); - if (!(sc->chip & RTWN_CHIP_88E)) { + if (!(sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E))) { /* Setup AMPDU aggregation. */ rtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */ rtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16); @@ -2837,7 +3144,7 @@ rtwn_init(struct ifnet *ifp) sc->sc_ops.bb_init(sc->sc_ops.cookie); rtwn_rf_init(sc); - if (sc->chip & RTWN_CHIP_88E) { + if (sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E)) { rtwn_write_2(sc, R92C_CR, rtwn_read_2(sc, R92C_CR) | R92C_CR_MACTXEN | R92C_CR_MACRXEN); @@ -2857,18 +3164,28 @@ rtwn_init(struct ifnet *ifp) /* Enable hardware sequence numbering. */ rtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff); + if (sc->chip & RTWN_CHIP_92E) { + rtwn_write_4(sc, R92C_BAR_MODE_CTRL, 0x0201ffff); + rtwn_write_1(sc, R92C_NAV_UPPER, 0); + + rtwn_write_1(sc, R92C_QUEUE_CTRL, + rtwn_read_1(sc, R92C_QUEUE_CTRL) & ~0x08); + } + /* Perform LO and IQ calibrations. */ rtwn_iq_calib(sc); /* Perform LC calibration. */ rtwn_lc_calib(sc); /* Fix USB interference issue. */ - if ((sc->chip & RTWN_CHIP_USB) && !(sc->chip & RTWN_CHIP_88E)) { - rtwn_write_1(sc, 0xfe40, 0xe0); - rtwn_write_1(sc, 0xfe41, 0x8d); - rtwn_write_1(sc, 0xfe42, 0x80); + if (sc->chip & RTWN_CHIP_USB) { + if (!(sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E))) { + rtwn_write_1(sc, 0xfe40, 0xe0); + rtwn_write_1(sc, 0xfe41, 0x8d); + rtwn_write_1(sc, 0xfe42, 0x80); - rtwn_pa_bias_init(sc); + rtwn_pa_bias_init(sc); + } } /* Initialize GPIO setting. */ @@ -2876,7 +3193,7 @@ rtwn_init(struct ifnet *ifp) rtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT); /* Fix for lower temperature. */ - if (!(sc->chip & RTWN_CHIP_88E)) + if (!(sc->chip & (RTWN_CHIP_88E | RTWN_CHIP_92E))) rtwn_write_1(sc, 0x15, 0xe9); /* Set default channel. */ diff --git a/sys/dev/ic/rtwnvar.h b/sys/dev/ic/rtwnvar.h index 885332dad9e..6386e4c9e07 100644 --- a/sys/dev/ic/rtwnvar.h +++ b/sys/dev/ic/rtwnvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rtwnvar.h,v 1.13 2018/10/01 22:36:08 jmatthew Exp $ */ +/* $OpenBSD: rtwnvar.h,v 1.14 2018/12/04 10:47:32 jmatthew Exp $ */ /*- * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> @@ -102,10 +102,12 @@ struct rtwn_softc { int fwcur; union { struct r92c_rom r92c_rom; + struct r92e_rom r92e_rom; struct r88e_rom r88e_rom; struct r23a_rom r23a_rom; } u; #define sc_r92c_rom u.r92c_rom +#define sc_r92e_rom u.r92e_rom #define sc_r88e_rom u.r88e_rom #define sc_r23a_rom u.r23a_rom |