summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
diff options
context:
space:
mode:
authorBitterblue Smith <rtl8821cerfe2@gmail.com>2023-03-13 16:58:14 +0300
committerKalle Valo <kvalo@kernel.org>2023-03-20 08:54:42 +0300
commit70664495e3d24803ec47ccaccee9a822220558a0 (patch)
tree315203dd70d21deebf63c909d13d66065fd84b9b /drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
parentd46e04ccd40457a0119b76e11ab64a2ad403e138 (diff)
downloadlinux-70664495e3d24803ec47ccaccee9a822220558a0.tar.xz
wifi: rtl8xxxu: Support new chip RTL8710BU aka RTL8188GU
This chip is found in cheap "free driver" USB adapters from Aliexpress. Initially they pretend to be a CD-ROM containing the driver for Windows. "Ejecting" switches the device to wifi mode. Features: 2.4 GHz, b/g/n mode, 1T1R, 150 Mbps. This chip is more unique than other Realtek chips: * The registers at addresses 0x0-0xff, which all the other chips use, can't be used here. New registers at 0x8000-0x80ff must be used instead. And it's not a simple matter of adding 0x8000: 0x2 (REG_SYS_FUNC) became 0x8004, 0x80 (REG_MCU_FW_DL) became 0x8090, etc. * Also there are a few new registers which must be accessed indirectly because their addresses don't fit in 16 bits. No other chips seem to have these. * The vendor driver compiles to 8188gu.ko, but the code calls the chip RTL8710B(U) pretty much everywhere, including messages visible to the user. Another difference compared to the other chips supported by rtl8xxxu is that it has a new PHY status struct, or three of them actually, from which we extract the RSSI, among other things. This is not unique, though, just new. The chips supported by rtw88 also use it. Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com> Reviewed-by: Ping-Ke Shih <pkshih@realtek.com> Tested-by: Philipp Hortmann <philipp.g.hortmann@gmail.com> # Edimax N150 Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/4edbe29f-00b9-8eef-9789-20bed0b141e2@gmail.com
Diffstat (limited to 'drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h')
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h313
1 files changed, 310 insertions, 3 deletions
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
index c8cee4a24755..9d48c69ffece 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -103,7 +103,8 @@ enum rtl8xxxu_rtl_chip {
RTL8822B = 0x8822b,
RTL8703B = 0x8703b,
RTL8195A = 0x8195a,
- RTL8188F = 0x8188f
+ RTL8188F = 0x8188f,
+ RTL8710B = 0x8710b,
};
enum rtl8xxxu_rx_type {
@@ -618,6 +619,265 @@ struct rtl8723au_phy_stats {
#endif
};
+struct jaguar2_phy_stats_type0 {
+ /* DW0 */
+ u8 page_num;
+ u8 pwdb;
+#ifdef __LITTLE_ENDIAN
+ u8 gain: 6;
+ u8 rsvd_0: 1;
+ u8 trsw: 1;
+#else
+ u8 trsw: 1;
+ u8 rsvd_0: 1;
+ u8 gain: 6;
+#endif
+ u8 rsvd_1;
+
+ /* DW1 */
+ u8 rsvd_2;
+#ifdef __LITTLE_ENDIAN
+ u8 rxsc: 4;
+ u8 agc_table: 4;
+#else
+ u8 agc_table: 4;
+ u8 rxsc: 4;
+#endif
+ u8 channel;
+ u8 band;
+
+ /* DW2 */
+ u16 length;
+#ifdef __LITTLE_ENDIAN
+ u8 antidx_a: 3;
+ u8 antidx_b: 3;
+ u8 rsvd_3: 2;
+ u8 antidx_c: 3;
+ u8 antidx_d: 3;
+ u8 rsvd_4:2;
+#else
+ u8 rsvd_3: 2;
+ u8 antidx_b: 3;
+ u8 antidx_a: 3;
+ u8 rsvd_4:2;
+ u8 antidx_d: 3;
+ u8 antidx_c: 3;
+#endif
+
+ /* DW3 */
+ u8 signal_quality;
+#ifdef __LITTLE_ENDIAN
+ u8 vga:5;
+ u8 lna_l:3;
+ u8 bb_power:6;
+ u8 rsvd_9:1;
+ u8 lna_h:1;
+#else
+ u8 lna_l:3;
+ u8 vga:5;
+ u8 lna_h:1;
+ u8 rsvd_9:1;
+ u8 bb_power:6;
+#endif
+ u8 rsvd_5;
+
+ /* DW4 */
+ u32 rsvd_6;
+
+ /* DW5 */
+ u32 rsvd_7;
+
+ /* DW6 */
+ u32 rsvd_8;
+} __packed;
+
+struct jaguar2_phy_stats_type1 {
+ /* DW0 and DW1 */
+ u8 page_num;
+ u8 pwdb[4];
+#ifdef __LITTLE_ENDIAN
+ u8 l_rxsc: 4;
+ u8 ht_rxsc: 4;
+#else
+ u8 ht_rxsc: 4;
+ u8 l_rxsc: 4;
+#endif
+ u8 channel;
+#ifdef __LITTLE_ENDIAN
+ u8 band: 2;
+ u8 rsvd_0: 1;
+ u8 hw_antsw_occu: 1;
+ u8 gnt_bt: 1;
+ u8 ldpc: 1;
+ u8 stbc: 1;
+ u8 beamformed: 1;
+#else
+ u8 beamformed: 1;
+ u8 stbc: 1;
+ u8 ldpc: 1;
+ u8 gnt_bt: 1;
+ u8 hw_antsw_occu: 1;
+ u8 rsvd_0: 1;
+ u8 band: 2;
+#endif
+
+ /* DW2 */
+ u16 lsig_length;
+#ifdef __LITTLE_ENDIAN
+ u8 antidx_a: 3;
+ u8 antidx_b: 3;
+ u8 rsvd_1: 2;
+ u8 antidx_c: 3;
+ u8 antidx_d: 3;
+ u8 rsvd_2: 2;
+#else
+ u8 rsvd_1: 2;
+ u8 antidx_b: 3;
+ u8 antidx_a: 3;
+ u8 rsvd_2: 2;
+ u8 antidx_d: 3;
+ u8 antidx_c: 3;
+#endif
+
+ /* DW3 */
+ u8 paid;
+#ifdef __LITTLE_ENDIAN
+ u8 paid_msb: 1;
+ u8 gid: 6;
+ u8 rsvd_3: 1;
+#else
+ u8 rsvd_3: 1;
+ u8 gid: 6;
+ u8 paid_msb: 1;
+#endif
+ u8 intf_pos;
+#ifdef __LITTLE_ENDIAN
+ u8 intf_pos_msb: 1;
+ u8 rsvd_4: 2;
+ u8 nb_intf_flag: 1;
+ u8 rf_mode: 2;
+ u8 rsvd_5: 2;
+#else
+ u8 rsvd_5: 2;
+ u8 rf_mode: 2;
+ u8 nb_intf_flag: 1;
+ u8 rsvd_4: 2;
+ u8 intf_pos_msb: 1;
+#endif
+
+ /* DW4 */
+ s8 rxevm[4]; /* s(8,1) */
+
+ /* DW5 */
+ s8 cfo_tail[4]; /* s(8,7) */
+
+ /* DW6 */
+ s8 rxsnr[4]; /* s(8,1) */
+} __packed;
+
+struct jaguar2_phy_stats_type2 {
+ /* DW0 ane DW1 */
+ u8 page_num;
+ u8 pwdb[4];
+#ifdef __LITTLE_ENDIAN
+ u8 l_rxsc: 4;
+ u8 ht_rxsc: 4;
+#else
+ u8 ht_rxsc: 4;
+ u8 l_rxsc: 4;
+#endif
+ u8 channel;
+#ifdef __LITTLE_ENDIAN
+ u8 band: 2;
+ u8 rsvd_0: 1;
+ u8 hw_antsw_occu: 1;
+ u8 gnt_bt: 1;
+ u8 ldpc: 1;
+ u8 stbc: 1;
+ u8 beamformed: 1;
+#else
+ u8 beamformed: 1;
+ u8 stbc: 1;
+ u8 ldpc: 1;
+ u8 gnt_bt: 1;
+ u8 hw_antsw_occu: 1;
+ u8 rsvd_0: 1;
+ u8 band: 2;
+#endif
+
+ /* DW2 */
+#ifdef __LITTLE_ENDIAN
+ u8 shift_l_map: 6;
+ u8 rsvd_1: 2;
+#else
+ u8 rsvd_1: 2;
+ u8 shift_l_map: 6;
+#endif
+ u8 cnt_pw2cca;
+#ifdef __LITTLE_ENDIAN
+ u8 agc_table_a: 4;
+ u8 agc_table_b: 4;
+ u8 agc_table_c: 4;
+ u8 agc_table_d: 4;
+#else
+ u8 agc_table_b: 4;
+ u8 agc_table_a: 4;
+ u8 agc_table_d: 4;
+ u8 agc_table_c: 4;
+#endif
+
+ /* DW3 ~ DW6*/
+ u8 cnt_cca2agc_rdy;
+#ifdef __LITTLE_ENDIAN
+ u8 gain_a: 6;
+ u8 rsvd_2: 1;
+ u8 trsw_a: 1;
+ u8 gain_b: 6;
+ u8 rsvd_3: 1;
+ u8 trsw_b: 1;
+ u8 gain_c: 6;
+ u8 rsvd_4: 1;
+ u8 trsw_c: 1;
+ u8 gain_d: 6;
+ u8 rsvd_5: 1;
+ u8 trsw_d: 1;
+ u8 aagc_step_a: 2;
+ u8 aagc_step_b: 2;
+ u8 aagc_step_c: 2;
+ u8 aagc_step_d: 2;
+#else
+ u8 trsw_a: 1;
+ u8 rsvd_2: 1;
+ u8 gain_a: 6;
+ u8 trsw_b: 1;
+ u8 rsvd_3: 1;
+ u8 gain_b: 6;
+ u8 trsw_c: 1;
+ u8 rsvd_4: 1;
+ u8 gain_c: 6;
+ u8 trsw_d: 1;
+ u8 rsvd_5: 1;
+ u8 gain_d: 6;
+ u8 aagc_step_d: 2;
+ u8 aagc_step_c: 2;
+ u8 aagc_step_b: 2;
+ u8 aagc_step_a: 2;
+#endif
+ u8 ht_aagc_gain[4];
+ u8 dagc_gain[4];
+#ifdef __LITTLE_ENDIAN
+ u8 counter: 6;
+ u8 rsvd_6: 2;
+ u8 syn_count: 5;
+ u8 rsvd_7:3;
+#else
+ u8 rsvd_6: 2;
+ u8 counter: 6;
+ u8 rsvd_7:3;
+ u8 syn_count: 5;
+#endif
+} __packed;
+
/*
* Regs to backup
*/
@@ -963,6 +1223,29 @@ struct rtl8188eu_efuse {
u8 res12[0xc3];
} __packed;
+struct rtl8710bu_efuse {
+ __le16 rtl_id;
+ u8 res0[0x1e];
+ struct rtl8188fu_efuse_tx_power tx_power_index_A; /* 0x20 */
+ u8 res1[0x9c]; /* 0x2c */
+ u8 channel_plan; /* 0xc8 */
+ u8 xtal_k; /* 0xc9 */
+ u8 thermal_meter; /* 0xca */
+ u8 res2[0x4f];
+ u8 mac_addr[ETH_ALEN]; /* 0x11a */
+ u8 res3[0x11];
+ u8 rf_board_option; /* 0x131 */
+ u8 res4[2];
+ u8 eeprom_version; /* 0x134 */
+ u8 eeprom_customer_id; /* 0x135 */
+ u8 res5[5];
+ u8 country_code; /* 0x13b */
+ u8 res6[0x84];
+ u8 vid[2]; /* 0x1c0 */
+ u8 pid[2]; /* 0x1c2 */
+ u8 res7[0x3c];
+} __packed;
+
struct rtl8xxxu_reg8val {
u16 reg;
u8 val;
@@ -1486,6 +1769,7 @@ struct rtl8xxxu_priv {
struct rtl8723au_idx ht20_tx_power_diff[RTL8723B_TX_COUNT];
struct rtl8723au_idx ht40_tx_power_diff[RTL8723B_TX_COUNT];
struct rtl8xxxu_power_base *power_base;
+ u8 package_type;
u32 chip_cut:4;
u32 rom_rev:4;
u32 is_multi_func:1;
@@ -1505,6 +1789,7 @@ struct rtl8xxxu_priv {
u32 ep_tx_low_queue:1;
u32 rx_buf_aggregation:1;
u32 cck_agc_report_type:1;
+ u32 cck_new_agc:1;
u8 default_crystal_cap;
unsigned int pipe_interrupt;
unsigned int pipe_in;
@@ -1522,6 +1807,8 @@ struct rtl8xxxu_priv {
int nr_out_eps;
struct mutex h2c_mutex;
+ /* Protect the indirect register accesses of RTL8710BU. */
+ struct mutex syson_indirect_access_mutex;
struct usb_anchor rx_anchor;
struct usb_anchor tx_anchor;
@@ -1542,6 +1829,7 @@ struct rtl8xxxu_priv {
struct rtl8192eu_efuse efuse8192eu;
struct rtl8188fu_efuse efuse8188fu;
struct rtl8188eu_efuse efuse8188eu;
+ struct rtl8710bu_efuse efuse8710bu;
} efuse_wifi;
u32 adda_backup[RTL8XXXU_ADDA_REGS];
u32 mac_backup[RTL8XXXU_MAC_REGS];
@@ -1586,6 +1874,7 @@ struct rtl8xxxu_tx_urb {
struct rtl8xxxu_fileops {
int (*identify_chip) (struct rtl8xxxu_priv *priv);
+ int (*read_efuse) (struct rtl8xxxu_priv *priv);
int (*parse_efuse) (struct rtl8xxxu_priv *priv);
int (*load_firmware) (struct rtl8xxxu_priv *priv);
int (*power_on) (struct rtl8xxxu_priv *priv);
@@ -1599,6 +1888,11 @@ struct rtl8xxxu_fileops {
void (*phy_iq_calibrate) (struct rtl8xxxu_priv *priv);
void (*config_channel) (struct ieee80211_hw *hw);
int (*parse_rx_desc) (struct rtl8xxxu_priv *priv, struct sk_buff *skb);
+ void (*parse_phystats) (struct rtl8xxxu_priv *priv,
+ struct ieee80211_rx_status *rx_status,
+ struct rtl8723au_phy_stats *phy_stats,
+ u32 rxmcs, struct ieee80211_hdr *hdr,
+ bool crc_icv_err);
void (*init_aggregation) (struct rtl8xxxu_priv *priv);
void (*init_statistics) (struct rtl8xxxu_priv *priv);
void (*init_burst) (struct rtl8xxxu_priv *priv);
@@ -1618,7 +1912,7 @@ struct rtl8xxxu_fileops {
bool short_preamble, bool ampdu_enable,
u32 rts_rate);
void (*set_crystal_cap) (struct rtl8xxxu_priv *priv, u8 crystal_cap);
- s8 (*cck_rssi) (struct rtl8xxxu_priv *priv, u8 cck_agc_rpt);
+ s8 (*cck_rssi) (struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats);
int (*led_classdev_brightness_set) (struct led_classdev *led_cdev,
enum led_brightness brightness);
int writeN_block_size;
@@ -1687,10 +1981,12 @@ void rtl8xxxu_identify_vendor_2bits(struct rtl8xxxu_priv *priv, u32 vendor);
void rtl8xxxu_config_endpoints_sie(struct rtl8xxxu_priv *priv);
int rtl8xxxu_config_endpoints_no_sie(struct rtl8xxxu_priv *priv);
int rtl8xxxu_read_efuse8(struct rtl8xxxu_priv *priv, u16 offset, u8 *data);
+int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv);
void rtl8xxxu_reset_8051(struct rtl8xxxu_priv *priv);
int rtl8xxxu_auto_llt_table(struct rtl8xxxu_priv *priv);
void rtl8xxxu_gen2_prepare_calibrate(struct rtl8xxxu_priv *priv, u8 start);
void rtl8723a_phy_lc_calibrate(struct rtl8xxxu_priv *priv);
+void rtl8188f_phy_lc_calibrate(struct rtl8xxxu_priv *priv);
int rtl8xxxu_flush_fifo(struct rtl8xxxu_priv *priv);
int rtl8xxxu_gen2_h2c_cmd(struct rtl8xxxu_priv *priv,
struct h2c_cmd *h2c, int len);
@@ -1724,6 +2020,16 @@ void rtl8xxxu_gen2_disable_rf(struct rtl8xxxu_priv *priv);
void rtl8xxxu_init_burst(struct rtl8xxxu_priv *priv);
int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
+void rtl8723au_rx_parse_phystats(struct rtl8xxxu_priv *priv,
+ struct ieee80211_rx_status *rx_status,
+ struct rtl8723au_phy_stats *phy_stats,
+ u32 rxmcs, struct ieee80211_hdr *hdr,
+ bool crc_icv_err);
+void jaguar2_rx_parse_phystats(struct rtl8xxxu_priv *priv,
+ struct ieee80211_rx_status *rx_status,
+ struct rtl8723au_phy_stats *phy_stats,
+ u32 rxmcs, struct ieee80211_hdr *hdr,
+ bool crc_icv_err);
int rtl8xxxu_gen2_channel_to_group(int channel);
bool rtl8xxxu_simularity_compare(struct rtl8xxxu_priv *priv,
int result[][8], int c1, int c2);
@@ -1749,12 +2055,13 @@ void rtl8723bu_set_ps_tdma(struct rtl8xxxu_priv *priv,
void rtl8723bu_phy_init_antenna_selection(struct rtl8xxxu_priv *priv);
void rtl8723a_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap);
void rtl8188f_set_crystal_cap(struct rtl8xxxu_priv *priv, u8 crystal_cap);
-s8 rtl8723a_cck_rssi(struct rtl8xxxu_priv *priv, u8 cck_agc_rpt);
+s8 rtl8723a_cck_rssi(struct rtl8xxxu_priv *priv, struct rtl8723au_phy_stats *phy_stats);
void rtl8xxxu_update_ra_report(struct rtl8xxxu_ra_report *rarpt,
u8 rate, u8 sgi, u8 bw);
void rtl8188e_ra_info_init_all(struct rtl8xxxu_ra_info *ra);
void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *skb);
+extern struct rtl8xxxu_fileops rtl8710bu_fops;
extern struct rtl8xxxu_fileops rtl8188fu_fops;
extern struct rtl8xxxu_fileops rtl8188eu_fops;
extern struct rtl8xxxu_fileops rtl8192cu_fops;