diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88')
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/fw.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/hci.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/mac.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/mac80211.c | 32 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/main.c | 39 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/main.h | 38 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/pci.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/phy.c | 1273 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/phy.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/regd.c | 69 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/regd.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8822c.c | 436 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8822c.h | 23 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/rtw8822c_table.c | 799 | ||||
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/tx.c | 2 |
15 files changed, 2042 insertions, 717 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index cf4265cda224..628477971213 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -8,7 +8,8 @@ #include "reg.h" #include "debug.h" -void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, struct sk_buff *skb) +static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, + struct sk_buff *skb) { struct rtw_c2h_cmd *c2h; u8 sub_cmd_id; @@ -47,7 +48,8 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb) } } -void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, u8 *h2c) +static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, + u8 *h2c) { u8 box; u8 box_state; diff --git a/drivers/net/wireless/realtek/rtw88/hci.h b/drivers/net/wireless/realtek/rtw88/hci.h index 2676582a85a0..aba329c9d0cf 100644 --- a/drivers/net/wireless/realtek/rtw88/hci.h +++ b/drivers/net/wireless/realtek/rtw88/hci.h @@ -97,7 +97,7 @@ static inline void rtw_write8_set(struct rtw_dev *rtwdev, u32 addr, u8 bit) rtw_write8(rtwdev, addr, val | bit); } -static inline void rtw_writ16_set(struct rtw_dev *rtwdev, u32 addr, u16 bit) +static inline void rtw_write16_set(struct rtw_dev *rtwdev, u32 addr, u16 bit) { u16 val; diff --git a/drivers/net/wireless/realtek/rtw88/mac.c b/drivers/net/wireless/realtek/rtw88/mac.c index 25a923bc6366..fc14b37d927d 100644 --- a/drivers/net/wireless/realtek/rtw88/mac.c +++ b/drivers/net/wireless/realtek/rtw88/mac.c @@ -285,8 +285,14 @@ int rtw_mac_power_on(struct rtw_dev *rtwdev) goto err; ret = rtw_mac_power_switch(rtwdev, true); - if (ret) + if (ret == -EALREADY) { + rtw_mac_power_switch(rtwdev, false); + ret = rtw_mac_power_switch(rtwdev, true); + if (ret) + goto err; + } else if (ret) { goto err; + } ret = rtw_mac_init_system_cfg(rtwdev); if (ret) diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c index abded63f138d..abe6a148673b 100644 --- a/drivers/net/wireless/realtek/rtw88/mac80211.c +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -85,30 +85,35 @@ static const struct rtw_vif_port rtw_vif_port[] = { .bssid = {.addr = 0x0618}, .net_type = {.addr = 0x0100, .mask = 0x30000}, .aid = {.addr = 0x06a8, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0550, .mask = 0xff}, }, [1] = { .mac_addr = {.addr = 0x0700}, .bssid = {.addr = 0x0708}, .net_type = {.addr = 0x0100, .mask = 0xc0000}, .aid = {.addr = 0x0710, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0551, .mask = 0xff}, }, [2] = { .mac_addr = {.addr = 0x1620}, .bssid = {.addr = 0x1628}, .net_type = {.addr = 0x1100, .mask = 0x3}, .aid = {.addr = 0x1600, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0578, .mask = 0xff}, }, [3] = { .mac_addr = {.addr = 0x1630}, .bssid = {.addr = 0x1638}, .net_type = {.addr = 0x1100, .mask = 0xc}, .aid = {.addr = 0x1604, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x0579, .mask = 0xff}, }, [4] = { .mac_addr = {.addr = 0x1640}, .bssid = {.addr = 0x1648}, .net_type = {.addr = 0x1100, .mask = 0x30}, .aid = {.addr = 0x1608, .mask = 0x7ff}, + .bcn_ctrl = {.addr = 0x057a, .mask = 0xff}, }, }; @@ -120,6 +125,7 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw, enum rtw_net_type net_type; u32 config = 0; u8 port = 0; + u8 bcn_ctrl = 0; rtwvif->port = port; rtwvif->vif = vif; @@ -136,13 +142,16 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: net_type = RTW_NET_AP_MODE; + bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT; break; case NL80211_IFTYPE_ADHOC: net_type = RTW_NET_AD_HOC; + bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT; break; case NL80211_IFTYPE_STATION: default: net_type = RTW_NET_NO_LINK; + bcn_ctrl = BIT_EN_BCN_FUNCTION; break; } @@ -150,6 +159,8 @@ static int rtw_ops_add_interface(struct ieee80211_hw *hw, config |= PORT_SET_MAC_ADDR; rtwvif->net_type = net_type; config |= PORT_SET_NET_TYPE; + rtwvif->bcn_ctrl = bcn_ctrl; + config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); mutex_unlock(&rtwdev->mutex); @@ -173,6 +184,8 @@ static void rtw_ops_remove_interface(struct ieee80211_hw *hw, config |= PORT_SET_MAC_ADDR; rtwvif->net_type = RTW_NET_NO_LINK; config |= PORT_SET_NET_TYPE; + rtwvif->bcn_ctrl = 0; + config |= PORT_SET_BCN_CTRL; rtw_vif_port_config(rtwdev, rtwvif, config); mutex_unlock(&rtwdev->mutex); @@ -446,20 +459,39 @@ static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw, { struct rtw_dev *rtwdev = hw->priv; struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + u32 config = 0; rtw_leave_lps(rtwdev, rtwvif); + mutex_lock(&rtwdev->mutex); + + ether_addr_copy(rtwvif->mac_addr, mac_addr); + config |= PORT_SET_MAC_ADDR; + rtw_vif_port_config(rtwdev, rtwvif, config); + rtw_flag_set(rtwdev, RTW_FLAG_DIG_DISABLE); rtw_flag_set(rtwdev, RTW_FLAG_SCANNING); + + mutex_unlock(&rtwdev->mutex); } static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct rtw_dev *rtwdev = hw->priv; + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + u32 config = 0; + + mutex_lock(&rtwdev->mutex); rtw_flag_clear(rtwdev, RTW_FLAG_SCANNING); rtw_flag_clear(rtwdev, RTW_FLAG_DIG_DISABLE); + + ether_addr_copy(rtwvif->mac_addr, vif->addr); + config |= PORT_SET_MAC_ADDR; + rtw_vif_port_config(rtwdev, rtwvif, config); + + mutex_unlock(&rtwdev->mutex); } const struct ieee80211_ops rtw_ops = { diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index f447361f7573..5a2c06267d07 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -20,7 +20,7 @@ EXPORT_SYMBOL(rtw_debug_mask); module_param_named(support_lps, rtw_fw_support_lps, bool, 0644); module_param_named(debug_mask, rtw_debug_mask, uint, 0644); -MODULE_PARM_DESC(support_lps, "Set Y to enable LPS support"); +MODULE_PARM_DESC(support_lps, "Set Y to enable Leisure Power Save support, to turn radio off between beacons"); MODULE_PARM_DESC(debug_mask, "Debugging mask"); static struct ieee80211_channel rtw_channeltable_2g[] = { @@ -162,7 +162,8 @@ static void rtw_watch_dog_work(struct work_struct *work) rtwdev->stats.tx_cnt = 0; rtwdev->stats.rx_cnt = 0; - rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); + /* use atomic version to avoid taking local->iflist_mtx mutex */ + rtw_iterate_vifs_atomic(rtwdev, rtw_vif_watch_dog_iter, &data); /* fw supports only one station associated to enter lps, if there are * more than two stations associated to the AP, then we can not enter @@ -197,15 +198,20 @@ void rtw_get_channel_params(struct cfg80211_chan_def *chandef, { struct ieee80211_channel *channel = chandef->chan; enum nl80211_chan_width width = chandef->width; + u8 *cch_by_bw = chan_params->cch_by_bw; u32 primary_freq, center_freq; u8 center_chan; u8 bandwidth = RTW_CHANNEL_WIDTH_20; u8 primary_chan_idx = 0; + u8 i; center_chan = channel->hw_value; primary_freq = channel->center_freq; center_freq = chandef->center_freq1; + /* assign the center channel used while 20M bw is selected */ + cch_by_bw[RTW_CHANNEL_WIDTH_20] = channel->hw_value; + switch (width) { case NL80211_CHAN_WIDTH_20_NOHT: case NL80211_CHAN_WIDTH_20: @@ -232,6 +238,10 @@ void rtw_get_channel_params(struct cfg80211_chan_def *chandef, primary_chan_idx = 3; center_chan -= 6; } + /* assign the center channel used + * while 40M bw is selected + */ + cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_chan + 4; } else { if (center_freq - primary_freq == 10) { primary_chan_idx = 2; @@ -240,6 +250,10 @@ void rtw_get_channel_params(struct cfg80211_chan_def *chandef, primary_chan_idx = 4; center_chan += 6; } + /* assign the center channel used + * while 40M bw is selected + */ + cch_by_bw[RTW_CHANNEL_WIDTH_40] = center_chan - 4; } break; default: @@ -250,6 +264,12 @@ void rtw_get_channel_params(struct cfg80211_chan_def *chandef, chan_params->center_chan = center_chan; chan_params->bandwidth = bandwidth; chan_params->primary_chan_idx = primary_chan_idx; + + /* assign the center channel used while current bw is selected */ + cch_by_bw[bandwidth] = center_chan; + + for (i = bandwidth + 1; i <= RTW_MAX_CHANNEL_WIDTH; i++) + cch_by_bw[i] = 0; } void rtw_set_channel(struct rtw_dev *rtwdev) @@ -259,6 +279,7 @@ void rtw_set_channel(struct rtw_dev *rtwdev) struct rtw_chip_info *chip = rtwdev->chip; struct rtw_channel_params ch_param; u8 center_chan, bandwidth, primary_chan_idx; + u8 i; rtw_get_channel_params(&hw->conf.chandef, &ch_param); if (WARN(ch_param.center_chan == 0, "Invalid channel\n")) @@ -271,6 +292,10 @@ void rtw_set_channel(struct rtw_dev *rtwdev) hal->current_band_width = bandwidth; hal->current_channel = center_chan; hal->current_band_type = center_chan > 14 ? RTW_BAND_5G : RTW_BAND_2G; + + for (i = RTW_CHANNEL_WIDTH_20; i <= RTW_MAX_CHANNEL_WIDTH; i++) + hal->cch_by_bw[i] = ch_param.cch_by_bw[i]; + chip->ops->set_channel(rtwdev, center_chan, bandwidth, primary_chan_idx); rtw_phy_set_tx_power_level(rtwdev, center_chan); @@ -308,6 +333,11 @@ void rtw_vif_port_config(struct rtw_dev *rtwdev, mask = rtwvif->conf->aid.mask; rtw_write32_mask(rtwdev, addr, mask, rtwvif->aid); } + if (config & PORT_SET_BCN_CTRL) { + addr = rtwvif->conf->bcn_ctrl.addr; + mask = rtwvif->conf->bcn_ctrl.mask; + rtw_write8_mask(rtwdev, addr, mask, rtwvif->bcn_ctrl); + } } static u8 hw_bw_cap_to_bitamp(u8 bw_cap) @@ -1041,7 +1071,7 @@ static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev) rtw_phy_setup_phy_cond(rtwdev, 0); - rtw_hw_init_tx_power(hal); + rtw_phy_init_tx_power(rtwdev); rtw_load_table(rtwdev, rfe_def->phy_pg_tbl); rtw_load_table(rtwdev, rfe_def->txpwr_lmt_tbl); rtw_phy_tx_power_by_rate_config(hal); @@ -1168,6 +1198,7 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); ieee80211_hw_set(hw, SUPPORTS_PS); ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SUPPORT_FAST_XMIT); hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | @@ -1177,6 +1208,8 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | WIPHY_FLAG_TDLS_EXTERNAL_SETUP; + hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; + rtw_set_supported_band(hw, rtwdev->chip); SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr); diff --git a/drivers/net/wireless/realtek/rtw88/main.h b/drivers/net/wireless/realtek/rtw88/main.h index 00fc77fb9b54..8fa05751836b 100644 --- a/drivers/net/wireless/realtek/rtw88/main.h +++ b/drivers/net/wireless/realtek/rtw88/main.h @@ -62,6 +62,9 @@ enum rtw_supported_band { RTW_BAND_MAX, }; +/* now, support upto 80M bw */ +#define RTW_MAX_CHANNEL_WIDTH RTW_CHANNEL_WIDTH_80 + enum rtw_bandwidth { RTW_CHANNEL_WIDTH_20 = 0, RTW_CHANNEL_WIDTH_40 = 1, @@ -286,10 +289,16 @@ enum rtw_trx_desc_rate { }; enum rtw_regulatory_domains { - RTW_REGD_FCC = 0, - RTW_REGD_MKK = 1, - RTW_REGD_ETSI = 2, - RTW_REGD_WW = 3, + RTW_REGD_FCC = 0, + RTW_REGD_MKK = 1, + RTW_REGD_ETSI = 2, + RTW_REGD_IC = 3, + RTW_REGD_KCC = 4, + RTW_REGD_ACMA = 5, + RTW_REGD_CHILE = 6, + RTW_REGD_UKRAINE = 7, + RTW_REGD_MEXICO = 8, + RTW_REGD_WW, RTW_REGD_MAX }; @@ -413,6 +422,10 @@ struct rtw_channel_params { u8 center_chan; u8 bandwidth; u8 primary_chan_idx; + /* center channel by different available bandwidth, + * val of (bw > current bandwidth) is invalid + */ + u8 cch_by_bw[RTW_MAX_CHANNEL_WIDTH + 1]; }; struct rtw_hw_reg { @@ -431,6 +444,7 @@ enum rtw_vif_port_set { PORT_SET_BSSID = BIT(1), PORT_SET_NET_TYPE = BIT(2), PORT_SET_AID = BIT(3), + PORT_SET_BCN_CTRL = BIT(4), }; struct rtw_vif_port { @@ -438,6 +452,7 @@ struct rtw_vif_port { struct rtw_hw_reg bssid; struct rtw_hw_reg net_type; struct rtw_hw_reg aid; + struct rtw_hw_reg bcn_ctrl; }; struct rtw_tx_pkt_info { @@ -591,6 +606,7 @@ struct rtw_vif { u8 mac_addr[ETH_ALEN]; u8 bssid[ETH_ALEN]; u8 port; + u8 bcn_ctrl; const struct rtw_vif_port *conf; struct rtw_traffic_stats stats; @@ -838,6 +854,9 @@ struct rtw_chip_info { u32 rfe_defs_size; }; +#define DACK_MSBK_BACKUP_NUM 0xf +#define DACK_DCK_BACKUP_NUM 0x2 + struct rtw_dm_info { u32 cck_fa_cnt; u32 ofdm_fa_cnt; @@ -853,6 +872,11 @@ struct rtw_dm_info { u8 cck_gi_u_bnd; u8 cck_gi_l_bnd; + + /* backup dack results for each path and I/Q */ + u32 dack_adck[RTW_RF_PATH_MAX]; + u16 dack_msbk[RTW_RF_PATH_MAX][2][DACK_MSBK_BACKUP_NUM]; + u8 dack_dck[RTW_RF_PATH_MAX][2][DACK_DCK_BACKUP_NUM]; }; struct rtw_efuse { @@ -973,6 +997,12 @@ struct rtw_hal { u8 current_channel; u8 current_band_width; u8 current_band_type; + + /* center channel for different available bandwidth, + * val of (bw > current_band_width) is invalid + */ + u8 cch_by_bw[RTW_MAX_CHANNEL_WIDTH + 1]; + u8 sec_ch_offset; u8 rf_type; u8 rf_path_num; diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c index cfe05ba7280d..353871c27779 100644 --- a/drivers/net/wireless/realtek/rtw88/pci.c +++ b/drivers/net/wireless/realtek/rtw88/pci.c @@ -487,10 +487,10 @@ static void rtw_pci_stop(struct rtw_dev *rtwdev) } static u8 ac_to_hwq[] = { - [0] = RTW_TX_QUEUE_VO, - [1] = RTW_TX_QUEUE_VI, - [2] = RTW_TX_QUEUE_BE, - [3] = RTW_TX_QUEUE_BK, + [IEEE80211_AC_VO] = RTW_TX_QUEUE_VO, + [IEEE80211_AC_VI] = RTW_TX_QUEUE_VI, + [IEEE80211_AC_BE] = RTW_TX_QUEUE_BE, + [IEEE80211_AC_BK] = RTW_TX_QUEUE_BK, }; static u8 rtw_hw_queue_mapping(struct sk_buff *skb) @@ -504,6 +504,8 @@ static u8 rtw_hw_queue_mapping(struct sk_buff *skb) queue = RTW_TX_QUEUE_BCN; else if (unlikely(ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))) queue = RTW_TX_QUEUE_MGMT; + else if (WARN_ON_ONCE(q_mapping >= ARRAY_SIZE(ac_to_hwq))) + queue = ac_to_hwq[IEEE80211_AC_BE]; else queue = ac_to_hwq[q_mapping]; diff --git a/drivers/net/wireless/realtek/rtw88/phy.c b/drivers/net/wireless/realtek/rtw88/phy.c index 4381b360b5b5..4ec8dcf17361 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.c +++ b/drivers/net/wireless/realtek/rtw88/phy.c @@ -65,6 +65,56 @@ static const u32 db_invert_table[12][8] = { 1995262315, 2511886432U, 3162277660U, 3981071706U} }; +u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M }; +u8 rtw_ofdm_rates[] = { + DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, + DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, + DESC_RATE48M, DESC_RATE54M +}; +u8 rtw_ht_1s_rates[] = { + DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, + DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, + DESC_RATEMCS6, DESC_RATEMCS7 +}; +u8 rtw_ht_2s_rates[] = { + DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, + DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13, + DESC_RATEMCS14, DESC_RATEMCS15 +}; +u8 rtw_vht_1s_rates[] = { + DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, + DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, + DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, + DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, + DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9 +}; +u8 rtw_vht_2s_rates[] = { + DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, + DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, + DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, + DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, + DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9 +}; +u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = { + rtw_cck_rates, rtw_ofdm_rates, + rtw_ht_1s_rates, rtw_ht_2s_rates, + rtw_vht_1s_rates, rtw_vht_2s_rates +}; +u8 rtw_rate_size[RTW_RATE_SECTION_MAX] = { + ARRAY_SIZE(rtw_cck_rates), + ARRAY_SIZE(rtw_ofdm_rates), + ARRAY_SIZE(rtw_ht_1s_rates), + ARRAY_SIZE(rtw_ht_2s_rates), + ARRAY_SIZE(rtw_vht_1s_rates), + ARRAY_SIZE(rtw_vht_2s_rates) +}; +static const u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates); +static const u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates); +static const u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates); +static const u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates); +static const u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates); +static const u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates); + enum rtw_phy_band_type { PHY_BAND_2G = 0, PHY_BAND_5G = 1, @@ -144,10 +194,10 @@ static void rtw_phy_stat_rssi_iter(void *data, struct ieee80211_sta *sta) struct rtw_phy_stat_iter_data *iter_data = data; struct rtw_dev *rtwdev = iter_data->rtwdev; struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; - u8 rssi, rssi_level; + u8 rssi; rssi = ewma_rssi_read(&si->avg_rssi); - rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi); + si->rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi); rtw_fw_send_rssi_info(rtwdev, si); @@ -423,6 +473,11 @@ static u64 rtw_phy_db_2_linear(u8 power_db) u8 i, j; u64 linear; + if (power_db > 96) + power_db = 96; + else if (power_db < 1) + return 1; + /* 1dB ~ 96dB */ i = (power_db - 1) >> 3; j = (power_db - 1) - (i << 3); @@ -596,14 +651,19 @@ bool rtw_phy_write_rf_reg(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, direct_addr = base_addr[rf_path] + (addr << 2); mask &= RFREG_MASK; - rtw_write32_mask(rtwdev, REG_RSV_CTRL, BITS_RFC_DIRECT, DISABLE_PI); - rtw_write32_mask(rtwdev, REG_WLRF1, BITS_RFC_DIRECT, DISABLE_PI); + if (addr == RF_CFGCH) { + rtw_write32_mask(rtwdev, REG_RSV_CTRL, BITS_RFC_DIRECT, DISABLE_PI); + rtw_write32_mask(rtwdev, REG_WLRF1, BITS_RFC_DIRECT, DISABLE_PI); + } + rtw_write32_mask(rtwdev, direct_addr, mask, data); udelay(1); - rtw_write32_mask(rtwdev, REG_RSV_CTRL, BITS_RFC_DIRECT, ENABLE_PI); - rtw_write32_mask(rtwdev, REG_WLRF1, BITS_RFC_DIRECT, ENABLE_PI); + if (addr == RF_CFGCH) { + rtw_write32_mask(rtwdev, REG_RSV_CTRL, BITS_RFC_DIRECT, ENABLE_PI); + rtw_write32_mask(rtwdev, REG_WLRF1, BITS_RFC_DIRECT, ENABLE_PI); + } return true; } @@ -709,6 +769,353 @@ void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl) } } +#define bcd_to_dec_pwr_by_rate(val, i) bcd2bin(val >> (i * 8)) + +static u8 tbl_to_dec_pwr_by_rate(struct rtw_dev *rtwdev, u32 hex, u8 i) +{ + if (rtwdev->chip->is_pwr_by_rate_dec) + return bcd_to_dec_pwr_by_rate(hex, i); + + return (hex >> (i * 8)) & 0xFF; +} + +static void +rtw_phy_get_rate_values_of_txpwr_by_rate(struct rtw_dev *rtwdev, + u32 addr, u32 mask, u32 val, u8 *rate, + u8 *pwr_by_rate, u8 *rate_num) +{ + int i; + + switch (addr) { + case 0xE00: + case 0x830: + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE04: + case 0x834: + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE08: + rate[0] = DESC_RATE1M; + pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 1); + *rate_num = 1; + break; + case 0x86C: + if (mask == 0xffffff00) { + rate[0] = DESC_RATE2M; + rate[1] = DESC_RATE5_5M; + rate[2] = DESC_RATE11M; + for (i = 1; i < 4; ++i) + pwr_by_rate[i - 1] = + tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 3; + } else if (mask == 0x000000ff) { + rate[0] = DESC_RATE11M; + pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 0); + *rate_num = 1; + } + break; + case 0xE10: + case 0x83C: + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE14: + case 0x848: + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE18: + case 0x84C: + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xE1C: + case 0x868: + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0x838: + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + for (i = 1; i < 4; ++i) + pwr_by_rate[i - 1] = tbl_to_dec_pwr_by_rate(rtwdev, + val, i); + *rate_num = 3; + break; + case 0xC20: + case 0xE20: + case 0x1820: + case 0x1A20: + rate[0] = DESC_RATE1M; + rate[1] = DESC_RATE2M; + rate[2] = DESC_RATE5_5M; + rate[3] = DESC_RATE11M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC24: + case 0xE24: + case 0x1824: + case 0x1A24: + rate[0] = DESC_RATE6M; + rate[1] = DESC_RATE9M; + rate[2] = DESC_RATE12M; + rate[3] = DESC_RATE18M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC28: + case 0xE28: + case 0x1828: + case 0x1A28: + rate[0] = DESC_RATE24M; + rate[1] = DESC_RATE36M; + rate[2] = DESC_RATE48M; + rate[3] = DESC_RATE54M; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC2C: + case 0xE2C: + case 0x182C: + case 0x1A2C: + rate[0] = DESC_RATEMCS0; + rate[1] = DESC_RATEMCS1; + rate[2] = DESC_RATEMCS2; + rate[3] = DESC_RATEMCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC30: + case 0xE30: + case 0x1830: + case 0x1A30: + rate[0] = DESC_RATEMCS4; + rate[1] = DESC_RATEMCS5; + rate[2] = DESC_RATEMCS6; + rate[3] = DESC_RATEMCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC34: + case 0xE34: + case 0x1834: + case 0x1A34: + rate[0] = DESC_RATEMCS8; + rate[1] = DESC_RATEMCS9; + rate[2] = DESC_RATEMCS10; + rate[3] = DESC_RATEMCS11; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC38: + case 0xE38: + case 0x1838: + case 0x1A38: + rate[0] = DESC_RATEMCS12; + rate[1] = DESC_RATEMCS13; + rate[2] = DESC_RATEMCS14; + rate[3] = DESC_RATEMCS15; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC3C: + case 0xE3C: + case 0x183C: + case 0x1A3C: + rate[0] = DESC_RATEVHT1SS_MCS0; + rate[1] = DESC_RATEVHT1SS_MCS1; + rate[2] = DESC_RATEVHT1SS_MCS2; + rate[3] = DESC_RATEVHT1SS_MCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC40: + case 0xE40: + case 0x1840: + case 0x1A40: + rate[0] = DESC_RATEVHT1SS_MCS4; + rate[1] = DESC_RATEVHT1SS_MCS5; + rate[2] = DESC_RATEVHT1SS_MCS6; + rate[3] = DESC_RATEVHT1SS_MCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC44: + case 0xE44: + case 0x1844: + case 0x1A44: + rate[0] = DESC_RATEVHT1SS_MCS8; + rate[1] = DESC_RATEVHT1SS_MCS9; + rate[2] = DESC_RATEVHT2SS_MCS0; + rate[3] = DESC_RATEVHT2SS_MCS1; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC48: + case 0xE48: + case 0x1848: + case 0x1A48: + rate[0] = DESC_RATEVHT2SS_MCS2; + rate[1] = DESC_RATEVHT2SS_MCS3; + rate[2] = DESC_RATEVHT2SS_MCS4; + rate[3] = DESC_RATEVHT2SS_MCS5; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xC4C: + case 0xE4C: + case 0x184C: + case 0x1A4C: + rate[0] = DESC_RATEVHT2SS_MCS6; + rate[1] = DESC_RATEVHT2SS_MCS7; + rate[2] = DESC_RATEVHT2SS_MCS8; + rate[3] = DESC_RATEVHT2SS_MCS9; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCD8: + case 0xED8: + case 0x18D8: + case 0x1AD8: + rate[0] = DESC_RATEMCS16; + rate[1] = DESC_RATEMCS17; + rate[2] = DESC_RATEMCS18; + rate[3] = DESC_RATEMCS19; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCDC: + case 0xEDC: + case 0x18DC: + case 0x1ADC: + rate[0] = DESC_RATEMCS20; + rate[1] = DESC_RATEMCS21; + rate[2] = DESC_RATEMCS22; + rate[3] = DESC_RATEMCS23; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCE0: + case 0xEE0: + case 0x18E0: + case 0x1AE0: + rate[0] = DESC_RATEVHT3SS_MCS0; + rate[1] = DESC_RATEVHT3SS_MCS1; + rate[2] = DESC_RATEVHT3SS_MCS2; + rate[3] = DESC_RATEVHT3SS_MCS3; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCE4: + case 0xEE4: + case 0x18E4: + case 0x1AE4: + rate[0] = DESC_RATEVHT3SS_MCS4; + rate[1] = DESC_RATEVHT3SS_MCS5; + rate[2] = DESC_RATEVHT3SS_MCS6; + rate[3] = DESC_RATEVHT3SS_MCS7; + for (i = 0; i < 4; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 4; + break; + case 0xCE8: + case 0xEE8: + case 0x18E8: + case 0x1AE8: + rate[0] = DESC_RATEVHT3SS_MCS8; + rate[1] = DESC_RATEVHT3SS_MCS9; + for (i = 0; i < 2; ++i) + pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); + *rate_num = 2; + break; + default: + rtw_warn(rtwdev, "invalid tx power index addr 0x%08x\n", addr); + break; + } +} + +static void rtw_phy_store_tx_power_by_rate(struct rtw_dev *rtwdev, + u32 band, u32 rfpath, u32 txnum, + u32 regaddr, u32 bitmask, u32 data) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 rate_num = 0; + u8 rate; + u8 rates[RTW_RF_PATH_MAX] = {0}; + s8 offset; + s8 pwr_by_rate[RTW_RF_PATH_MAX] = {0}; + int i; + + rtw_phy_get_rate_values_of_txpwr_by_rate(rtwdev, regaddr, bitmask, data, + rates, pwr_by_rate, &rate_num); + + if (WARN_ON(rfpath >= RTW_RF_PATH_MAX || + (band != PHY_BAND_2G && band != PHY_BAND_5G) || + rate_num > RTW_RF_PATH_MAX)) + return; + + for (i = 0; i < rate_num; i++) { + offset = pwr_by_rate[i]; + rate = rates[i]; + if (band == PHY_BAND_2G) + hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset; + else if (band == PHY_BAND_5G) + hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; + else + continue; + } +} + void rtw_parse_tbl_bb_pg(struct rtw_dev *rtwdev, const struct rtw_table *tbl) { const struct phy_pg_cfg_pair *p = tbl->data; @@ -721,12 +1128,142 @@ void rtw_parse_tbl_bb_pg(struct rtw_dev *rtwdev, const struct rtw_table *tbl) msleep(50); continue; } - phy_store_tx_power_by_rate(rtwdev, p->band, p->rf_path, - p->tx_num, p->addr, p->bitmask, - p->data); + rtw_phy_store_tx_power_by_rate(rtwdev, p->band, p->rf_path, + p->tx_num, p->addr, p->bitmask, + p->data); + } +} + +static const u8 rtw_channel_idx_5g[RTW_MAX_CHANNEL_NUM_5G] = { + 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ + 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ + 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ + 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ + 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ + 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ + 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ + +static int rtw_channel_to_idx(u8 band, u8 channel) +{ + int ch_idx; + u8 n_channel; + + if (band == PHY_BAND_2G) { + ch_idx = channel - 1; + n_channel = RTW_MAX_CHANNEL_NUM_2G; + } else if (band == PHY_BAND_5G) { + n_channel = RTW_MAX_CHANNEL_NUM_5G; + for (ch_idx = 0; ch_idx < n_channel; ch_idx++) + if (rtw_channel_idx_5g[ch_idx] == channel) + break; + } else { + return -1; + } + + if (ch_idx >= n_channel) + return -1; + + return ch_idx; +} + +static void rtw_phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band, + u8 bw, u8 rs, u8 ch, s8 pwr_limit) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 max_power_index = rtwdev->chip->max_power_index; + s8 ww; + int ch_idx; + + pwr_limit = clamp_t(s8, pwr_limit, + -max_power_index, max_power_index); + ch_idx = rtw_channel_to_idx(band, ch); + + if (regd >= RTW_REGD_MAX || bw >= RTW_CHANNEL_WIDTH_MAX || + rs >= RTW_RATE_SECTION_MAX || ch_idx < 0) { + WARN(1, + "wrong txpwr_lmt regd=%u, band=%u bw=%u, rs=%u, ch_idx=%u, pwr_limit=%d\n", + regd, band, bw, rs, ch_idx, pwr_limit); + return; + } + + if (band == PHY_BAND_2G) { + hal->tx_pwr_limit_2g[regd][bw][rs][ch_idx] = pwr_limit; + ww = hal->tx_pwr_limit_2g[RTW_REGD_WW][bw][rs][ch_idx]; + ww = min_t(s8, ww, pwr_limit); + hal->tx_pwr_limit_2g[RTW_REGD_WW][bw][rs][ch_idx] = ww; + } else if (band == PHY_BAND_5G) { + hal->tx_pwr_limit_5g[regd][bw][rs][ch_idx] = pwr_limit; + ww = hal->tx_pwr_limit_5g[RTW_REGD_WW][bw][rs][ch_idx]; + ww = min_t(s8, ww, pwr_limit); + hal->tx_pwr_limit_5g[RTW_REGD_WW][bw][rs][ch_idx] = ww; } } +/* cross-reference 5G power limits if values are not assigned */ +static void +rtw_xref_5g_txpwr_lmt(struct rtw_dev *rtwdev, u8 regd, + u8 bw, u8 ch_idx, u8 rs_ht, u8 rs_vht) +{ + struct rtw_hal *hal = &rtwdev->hal; + u8 max_power_index = rtwdev->chip->max_power_index; + s8 lmt_ht = hal->tx_pwr_limit_5g[regd][bw][rs_ht][ch_idx]; + s8 lmt_vht = hal->tx_pwr_limit_5g[regd][bw][rs_vht][ch_idx]; + + if (lmt_ht == lmt_vht) + return; + + if (lmt_ht == max_power_index) + hal->tx_pwr_limit_5g[regd][bw][rs_ht][ch_idx] = lmt_vht; + + else if (lmt_vht == max_power_index) + hal->tx_pwr_limit_5g[regd][bw][rs_vht][ch_idx] = lmt_ht; +} + +/* cross-reference power limits for ht and vht */ +static void +rtw_xref_txpwr_lmt_by_rs(struct rtw_dev *rtwdev, u8 regd, u8 bw, u8 ch_idx) +{ + u8 rs_idx, rs_ht, rs_vht; + u8 rs_cmp[2][2] = {{RTW_RATE_SECTION_HT_1S, RTW_RATE_SECTION_VHT_1S}, + {RTW_RATE_SECTION_HT_2S, RTW_RATE_SECTION_VHT_2S} }; + + for (rs_idx = 0; rs_idx < 2; rs_idx++) { + rs_ht = rs_cmp[rs_idx][0]; + rs_vht = rs_cmp[rs_idx][1]; + + rtw_xref_5g_txpwr_lmt(rtwdev, regd, bw, ch_idx, rs_ht, rs_vht); + } +} + +/* cross-reference power limits for 5G channels */ +static void +rtw_xref_5g_txpwr_lmt_by_ch(struct rtw_dev *rtwdev, u8 regd, u8 bw) +{ + u8 ch_idx; + + for (ch_idx = 0; ch_idx < RTW_MAX_CHANNEL_NUM_5G; ch_idx++) + rtw_xref_txpwr_lmt_by_rs(rtwdev, regd, bw, ch_idx); +} + +/* cross-reference power limits for 20/40M bandwidth */ +static void +rtw_xref_txpwr_lmt_by_bw(struct rtw_dev *rtwdev, u8 regd) +{ + u8 bw; + + for (bw = RTW_CHANNEL_WIDTH_20; bw <= RTW_CHANNEL_WIDTH_40; bw++) + rtw_xref_5g_txpwr_lmt_by_ch(rtwdev, regd, bw); +} + +/* cross-reference power limits */ +static void rtw_xref_txpwr_lmt(struct rtw_dev *rtwdev) +{ + u8 regd; + + for (regd = 0; regd < RTW_REGD_MAX; regd++) + rtw_xref_txpwr_lmt_by_bw(rtwdev, regd); +} + void rtw_parse_tbl_txpwr_lmt(struct rtw_dev *rtwdev, const struct rtw_table *tbl) { @@ -736,10 +1273,11 @@ void rtw_parse_tbl_txpwr_lmt(struct rtw_dev *rtwdev, BUILD_BUG_ON(sizeof(struct txpwr_lmt_cfg_pair) != sizeof(u8) * 6); for (; p < end; p++) { - phy_set_tx_power_limit(rtwdev, p->regd, p->band, - p->bw, p->rs, - p->ch, p->txpwr_lmt); + rtw_phy_set_tx_power_limit(rtwdev, p->regd, p->band, + p->bw, p->rs, p->ch, p->txpwr_lmt); } + + rtw_xref_txpwr_lmt(rtwdev); } void rtw_phy_cfg_mac(struct rtw_dev *rtwdev, const struct rtw_table *tbl, @@ -814,92 +1352,6 @@ void rtw_phy_load_tables(struct rtw_dev *rtwdev) } } -#define bcd_to_dec_pwr_by_rate(val, i) bcd2bin(val >> (i * 8)) - -#define RTW_MAX_POWER_INDEX 0x3F - -u8 rtw_cck_rates[] = { DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M }; -u8 rtw_ofdm_rates[] = { - DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, - DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, - DESC_RATE48M, DESC_RATE54M -}; -u8 rtw_ht_1s_rates[] = { - DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, - DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, - DESC_RATEMCS6, DESC_RATEMCS7 -}; -u8 rtw_ht_2s_rates[] = { - DESC_RATEMCS8, DESC_RATEMCS9, DESC_RATEMCS10, - DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13, - DESC_RATEMCS14, DESC_RATEMCS15 -}; -u8 rtw_vht_1s_rates[] = { - DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, - DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, - DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, - DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, - DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9 -}; -u8 rtw_vht_2s_rates[] = { - DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, - DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, - DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, - DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, - DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9 -}; -u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates); -u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates); -u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates); -u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates); -u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates); -u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates); -u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = { - rtw_cck_rates, rtw_ofdm_rates, - rtw_ht_1s_rates, rtw_ht_2s_rates, - rtw_vht_1s_rates, rtw_vht_2s_rates -}; -u8 rtw_rate_size[RTW_RATE_SECTION_MAX] = { - ARRAY_SIZE(rtw_cck_rates), - ARRAY_SIZE(rtw_ofdm_rates), - ARRAY_SIZE(rtw_ht_1s_rates), - ARRAY_SIZE(rtw_ht_2s_rates), - ARRAY_SIZE(rtw_vht_1s_rates), - ARRAY_SIZE(rtw_vht_2s_rates) -}; - -static const u8 rtw_channel_idx_5g[RTW_MAX_CHANNEL_NUM_5G] = { - 36, 38, 40, 42, 44, 46, 48, /* Band 1 */ - 52, 54, 56, 58, 60, 62, 64, /* Band 2 */ - 100, 102, 104, 106, 108, 110, 112, /* Band 3 */ - 116, 118, 120, 122, 124, 126, 128, /* Band 3 */ - 132, 134, 136, 138, 140, 142, 144, /* Band 3 */ - 149, 151, 153, 155, 157, 159, 161, /* Band 4 */ - 165, 167, 169, 171, 173, 175, 177}; /* Band 4 */ - -static int rtw_channel_to_idx(u8 band, u8 channel) -{ - int ch_idx; - u8 n_channel; - - if (band == PHY_BAND_2G) { - ch_idx = channel - 1; - n_channel = RTW_MAX_CHANNEL_NUM_2G; - } else if (band == PHY_BAND_5G) { - n_channel = RTW_MAX_CHANNEL_NUM_5G; - for (ch_idx = 0; ch_idx < n_channel; ch_idx++) - if (rtw_channel_idx_5g[ch_idx] == channel) - break; - } else { - return -1; - } - - if (ch_idx >= n_channel) - return -1; - - return ch_idx; -} - static u8 rtw_get_channel_group(u8 channel) { switch (channel) { @@ -989,10 +1441,10 @@ static u8 rtw_get_channel_group(u8 channel) } } -static u8 phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, - struct rtw_2g_txpwr_idx *pwr_idx_2g, - enum rtw_bandwidth bandwidth, - u8 rate, u8 group) +static u8 rtw_phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, + struct rtw_2g_txpwr_idx *pwr_idx_2g, + enum rtw_bandwidth bandwidth, + u8 rate, u8 group) { struct rtw_chip_info *chip = rtwdev->chip; u8 tx_power; @@ -1036,10 +1488,10 @@ static u8 phy_get_2g_tx_power_index(struct rtw_dev *rtwdev, return tx_power; } -static u8 phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, - struct rtw_5g_txpwr_idx *pwr_idx_5g, - enum rtw_bandwidth bandwidth, - u8 rate, u8 group) +static u8 rtw_phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, + struct rtw_5g_txpwr_idx *pwr_idx_5g, + enum rtw_bandwidth bandwidth, + u8 rate, u8 group) { struct rtw_chip_info *chip = rtwdev->chip; u8 tx_power; @@ -1090,81 +1542,112 @@ static u8 phy_get_5g_tx_power_index(struct rtw_dev *rtwdev, return tx_power; } -/* set tx power level by path for each rates, note that the order of the rates - * are *very* important, bacause 8822B/8821C combines every four bytes of tx - * power index into a four-byte power index register, and calls set_tx_agc to - * write these values into hardware - */ -static -void phy_set_tx_power_level_by_path(struct rtw_dev *rtwdev, u8 ch, u8 path) +static s8 rtw_phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, + enum rtw_bandwidth bw, u8 rf_path, + u8 rate, u8 channel, u8 regd) { struct rtw_hal *hal = &rtwdev->hal; + u8 *cch_by_bw = hal->cch_by_bw; + s8 power_limit = (s8)rtwdev->chip->max_power_index; u8 rs; + int ch_idx; + u8 cur_bw, cur_ch; + s8 cur_lmt; - /* do not need cck rates if we are not in 2.4G */ - if (hal->current_band_type == RTW_BAND_2G) + if (regd > RTW_REGD_WW) + return power_limit; + + if (rate >= DESC_RATE1M && rate <= DESC_RATE11M) rs = RTW_RATE_SECTION_CCK; - else + else if (rate >= DESC_RATE6M && rate <= DESC_RATE54M) rs = RTW_RATE_SECTION_OFDM; + else if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS7) + rs = RTW_RATE_SECTION_HT_1S; + else if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) + rs = RTW_RATE_SECTION_HT_2S; + else if (rate >= DESC_RATEVHT1SS_MCS0 && rate <= DESC_RATEVHT1SS_MCS9) + rs = RTW_RATE_SECTION_VHT_1S; + else if (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9) + rs = RTW_RATE_SECTION_VHT_2S; + else + goto err; - for (; rs < RTW_RATE_SECTION_MAX; rs++) - phy_set_tx_power_index_by_rs(rtwdev, ch, path, rs); -} + /* only 20M BW with cck and ofdm */ + if (rs == RTW_RATE_SECTION_CCK || rs == RTW_RATE_SECTION_OFDM) + bw = RTW_CHANNEL_WIDTH_20; -void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel) -{ - struct rtw_chip_info *chip = rtwdev->chip; - struct rtw_hal *hal = &rtwdev->hal; - u8 path; + /* only 20/40M BW with ht */ + if (rs == RTW_RATE_SECTION_HT_1S || rs == RTW_RATE_SECTION_HT_2S) + bw = min_t(u8, bw, RTW_CHANNEL_WIDTH_40); - mutex_lock(&hal->tx_power_mutex); + /* select min power limit among [20M BW ~ current BW] */ + for (cur_bw = RTW_CHANNEL_WIDTH_20; cur_bw <= bw; cur_bw++) { + cur_ch = cch_by_bw[cur_bw]; - for (path = 0; path < hal->rf_path_num; path++) - phy_set_tx_power_level_by_path(rtwdev, channel, path); + ch_idx = rtw_channel_to_idx(band, cur_ch); + if (ch_idx < 0) + goto err; - chip->ops->set_tx_power_index(rtwdev); - mutex_unlock(&hal->tx_power_mutex); -} + cur_lmt = cur_ch <= RTW_MAX_CHANNEL_NUM_2G ? + hal->tx_pwr_limit_2g[regd][cur_bw][rs][ch_idx] : + hal->tx_pwr_limit_5g[regd][cur_bw][rs][ch_idx]; + + power_limit = min_t(s8, cur_lmt, power_limit); + } + + return power_limit; -s8 phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, - enum rtw_bandwidth bandwidth, u8 rf_path, - u8 rate, u8 channel, u8 regd); +err: + WARN(1, "invalid arguments, band=%d, bw=%d, path=%d, rate=%d, ch=%d\n", + band, bw, rf_path, rate, channel); + return (s8)rtwdev->chip->max_power_index; +} -static -u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate, - enum rtw_bandwidth bandwidth, u8 channel, u8 regd) +void rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, u8 rate, u8 bw, + u8 ch, u8 regd, struct rtw_power_params *pwr_param) { - struct rtw_dev *rtwdev = adapter; struct rtw_hal *hal = &rtwdev->hal; struct rtw_txpwr_idx *pwr_idx; - u8 tx_power; - u8 group; - u8 band; - s8 offset, limit; + u8 group, band; + u8 *base = &pwr_param->pwr_base; + s8 *offset = &pwr_param->pwr_offset; + s8 *limit = &pwr_param->pwr_limit; - pwr_idx = &rtwdev->efuse.txpwr_idx_table[rf_path]; - group = rtw_get_channel_group(channel); + pwr_idx = &rtwdev->efuse.txpwr_idx_table[path]; + group = rtw_get_channel_group(ch); /* base power index for 2.4G/5G */ - if (channel <= 14) { + if (ch <= 14) { band = PHY_BAND_2G; - tx_power = phy_get_2g_tx_power_index(rtwdev, - &pwr_idx->pwr_idx_2g, - bandwidth, rate, group); - offset = hal->tx_pwr_by_rate_offset_2g[rf_path][rate]; + *base = rtw_phy_get_2g_tx_power_index(rtwdev, + &pwr_idx->pwr_idx_2g, + bw, rate, group); + *offset = hal->tx_pwr_by_rate_offset_2g[path][rate]; } else { band = PHY_BAND_5G; - tx_power = phy_get_5g_tx_power_index(rtwdev, - &pwr_idx->pwr_idx_5g, - bandwidth, rate, group); - offset = hal->tx_pwr_by_rate_offset_5g[rf_path][rate]; + *base = rtw_phy_get_5g_tx_power_index(rtwdev, + &pwr_idx->pwr_idx_5g, + bw, rate, group); + *offset = hal->tx_pwr_by_rate_offset_5g[path][rate]; } - limit = phy_get_tx_power_limit(rtwdev, band, bandwidth, rf_path, - rate, channel, regd); + *limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path, + rate, ch, regd); +} + +u8 +rtw_phy_get_tx_power_index(struct rtw_dev *rtwdev, u8 rf_path, u8 rate, + enum rtw_bandwidth bandwidth, u8 channel, u8 regd) +{ + struct rtw_power_params pwr_param = {0}; + u8 tx_power; + s8 offset; + + rtw_get_tx_power_params(rtwdev, rf_path, rate, bandwidth, + channel, regd, &pwr_param); - if (offset > limit) - offset = limit; + tx_power = pwr_param.pwr_base; + offset = min_t(s8, pwr_param.pwr_offset, pwr_param.pwr_limit); tx_power += offset; @@ -1174,9 +1657,9 @@ u8 phy_get_tx_power_index(void *adapter, u8 rf_path, u8 rate, return tx_power; } -void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs) +static void rtw_phy_set_tx_power_index_by_rs(struct rtw_dev *rtwdev, + u8 ch, u8 path, u8 rs) { - struct rtw_dev *rtwdev = adapter; struct rtw_hal *hal = &rtwdev->hal; u8 regd = rtwdev->regd.txpwr_regd; u8 *rates; @@ -1194,361 +1677,51 @@ void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs) bw = hal->current_band_width; for (i = 0; i < size; i++) { rate = rates[i]; - pwr_idx = phy_get_tx_power_index(adapter, path, rate, bw, ch, - regd); + pwr_idx = rtw_phy_get_tx_power_index(rtwdev, path, rate, + bw, ch, regd); hal->tx_pwr_tbl[path][rate] = pwr_idx; } } -static u8 tbl_to_dec_pwr_by_rate(struct rtw_dev *rtwdev, u32 hex, u8 i) -{ - if (rtwdev->chip->is_pwr_by_rate_dec) - return bcd_to_dec_pwr_by_rate(hex, i); - else - return (hex >> (i * 8)) & 0xFF; -} - -static void phy_get_rate_values_of_txpwr_by_rate(struct rtw_dev *rtwdev, - u32 addr, u32 mask, - u32 val, u8 *rate, - u8 *pwr_by_rate, u8 *rate_num) +/* set tx power level by path for each rates, note that the order of the rates + * are *very* important, bacause 8822B/8821C combines every four bytes of tx + * power index into a four-byte power index register, and calls set_tx_agc to + * write these values into hardware + */ +static void rtw_phy_set_tx_power_level_by_path(struct rtw_dev *rtwdev, + u8 ch, u8 path) { - int i; + struct rtw_hal *hal = &rtwdev->hal; + u8 rs; - switch (addr) { - case 0xE00: - case 0x830: - rate[0] = DESC_RATE6M; - rate[1] = DESC_RATE9M; - rate[2] = DESC_RATE12M; - rate[3] = DESC_RATE18M; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xE04: - case 0x834: - rate[0] = DESC_RATE24M; - rate[1] = DESC_RATE36M; - rate[2] = DESC_RATE48M; - rate[3] = DESC_RATE54M; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xE08: - rate[0] = DESC_RATE1M; - pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 1); - *rate_num = 1; - break; - case 0x86C: - if (mask == 0xffffff00) { - rate[0] = DESC_RATE2M; - rate[1] = DESC_RATE5_5M; - rate[2] = DESC_RATE11M; - for (i = 1; i < 4; ++i) - pwr_by_rate[i - 1] = - tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 3; - } else if (mask == 0x000000ff) { - rate[0] = DESC_RATE11M; - pwr_by_rate[0] = bcd_to_dec_pwr_by_rate(val, 0); - *rate_num = 1; - } - break; - case 0xE10: - case 0x83C: - rate[0] = DESC_RATEMCS0; - rate[1] = DESC_RATEMCS1; - rate[2] = DESC_RATEMCS2; - rate[3] = DESC_RATEMCS3; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xE14: - case 0x848: - rate[0] = DESC_RATEMCS4; - rate[1] = DESC_RATEMCS5; - rate[2] = DESC_RATEMCS6; - rate[3] = DESC_RATEMCS7; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xE18: - case 0x84C: - rate[0] = DESC_RATEMCS8; - rate[1] = DESC_RATEMCS9; - rate[2] = DESC_RATEMCS10; - rate[3] = DESC_RATEMCS11; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xE1C: - case 0x868: - rate[0] = DESC_RATEMCS12; - rate[1] = DESC_RATEMCS13; - rate[2] = DESC_RATEMCS14; - rate[3] = DESC_RATEMCS15; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; + /* do not need cck rates if we are not in 2.4G */ + if (hal->current_band_type == RTW_BAND_2G) + rs = RTW_RATE_SECTION_CCK; + else + rs = RTW_RATE_SECTION_OFDM; - break; - case 0x838: - rate[0] = DESC_RATE1M; - rate[1] = DESC_RATE2M; - rate[2] = DESC_RATE5_5M; - for (i = 1; i < 4; ++i) - pwr_by_rate[i - 1] = tbl_to_dec_pwr_by_rate(rtwdev, - val, i); - *rate_num = 3; - break; - case 0xC20: - case 0xE20: - case 0x1820: - case 0x1A20: - rate[0] = DESC_RATE1M; - rate[1] = DESC_RATE2M; - rate[2] = DESC_RATE5_5M; - rate[3] = DESC_RATE11M; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC24: - case 0xE24: - case 0x1824: - case 0x1A24: - rate[0] = DESC_RATE6M; - rate[1] = DESC_RATE9M; - rate[2] = DESC_RATE12M; - rate[3] = DESC_RATE18M; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC28: - case 0xE28: - case 0x1828: - case 0x1A28: - rate[0] = DESC_RATE24M; - rate[1] = DESC_RATE36M; - rate[2] = DESC_RATE48M; - rate[3] = DESC_RATE54M; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC2C: - case 0xE2C: - case 0x182C: - case 0x1A2C: - rate[0] = DESC_RATEMCS0; - rate[1] = DESC_RATEMCS1; - rate[2] = DESC_RATEMCS2; - rate[3] = DESC_RATEMCS3; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC30: - case 0xE30: - case 0x1830: - case 0x1A30: - rate[0] = DESC_RATEMCS4; - rate[1] = DESC_RATEMCS5; - rate[2] = DESC_RATEMCS6; - rate[3] = DESC_RATEMCS7; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC34: - case 0xE34: - case 0x1834: - case 0x1A34: - rate[0] = DESC_RATEMCS8; - rate[1] = DESC_RATEMCS9; - rate[2] = DESC_RATEMCS10; - rate[3] = DESC_RATEMCS11; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC38: - case 0xE38: - case 0x1838: - case 0x1A38: - rate[0] = DESC_RATEMCS12; - rate[1] = DESC_RATEMCS13; - rate[2] = DESC_RATEMCS14; - rate[3] = DESC_RATEMCS15; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC3C: - case 0xE3C: - case 0x183C: - case 0x1A3C: - rate[0] = DESC_RATEVHT1SS_MCS0; - rate[1] = DESC_RATEVHT1SS_MCS1; - rate[2] = DESC_RATEVHT1SS_MCS2; - rate[3] = DESC_RATEVHT1SS_MCS3; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC40: - case 0xE40: - case 0x1840: - case 0x1A40: - rate[0] = DESC_RATEVHT1SS_MCS4; - rate[1] = DESC_RATEVHT1SS_MCS5; - rate[2] = DESC_RATEVHT1SS_MCS6; - rate[3] = DESC_RATEVHT1SS_MCS7; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC44: - case 0xE44: - case 0x1844: - case 0x1A44: - rate[0] = DESC_RATEVHT1SS_MCS8; - rate[1] = DESC_RATEVHT1SS_MCS9; - rate[2] = DESC_RATEVHT2SS_MCS0; - rate[3] = DESC_RATEVHT2SS_MCS1; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC48: - case 0xE48: - case 0x1848: - case 0x1A48: - rate[0] = DESC_RATEVHT2SS_MCS2; - rate[1] = DESC_RATEVHT2SS_MCS3; - rate[2] = DESC_RATEVHT2SS_MCS4; - rate[3] = DESC_RATEVHT2SS_MCS5; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xC4C: - case 0xE4C: - case 0x184C: - case 0x1A4C: - rate[0] = DESC_RATEVHT2SS_MCS6; - rate[1] = DESC_RATEVHT2SS_MCS7; - rate[2] = DESC_RATEVHT2SS_MCS8; - rate[3] = DESC_RATEVHT2SS_MCS9; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xCD8: - case 0xED8: - case 0x18D8: - case 0x1AD8: - rate[0] = DESC_RATEMCS16; - rate[1] = DESC_RATEMCS17; - rate[2] = DESC_RATEMCS18; - rate[3] = DESC_RATEMCS19; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xCDC: - case 0xEDC: - case 0x18DC: - case 0x1ADC: - rate[0] = DESC_RATEMCS20; - rate[1] = DESC_RATEMCS21; - rate[2] = DESC_RATEMCS22; - rate[3] = DESC_RATEMCS23; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xCE0: - case 0xEE0: - case 0x18E0: - case 0x1AE0: - rate[0] = DESC_RATEVHT3SS_MCS0; - rate[1] = DESC_RATEVHT3SS_MCS1; - rate[2] = DESC_RATEVHT3SS_MCS2; - rate[3] = DESC_RATEVHT3SS_MCS3; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xCE4: - case 0xEE4: - case 0x18E4: - case 0x1AE4: - rate[0] = DESC_RATEVHT3SS_MCS4; - rate[1] = DESC_RATEVHT3SS_MCS5; - rate[2] = DESC_RATEVHT3SS_MCS6; - rate[3] = DESC_RATEVHT3SS_MCS7; - for (i = 0; i < 4; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 4; - break; - case 0xCE8: - case 0xEE8: - case 0x18E8: - case 0x1AE8: - rate[0] = DESC_RATEVHT3SS_MCS8; - rate[1] = DESC_RATEVHT3SS_MCS9; - for (i = 0; i < 2; ++i) - pwr_by_rate[i] = tbl_to_dec_pwr_by_rate(rtwdev, val, i); - *rate_num = 2; - break; - default: - rtw_warn(rtwdev, "invalid tx power index addr 0x%08x\n", addr); - break; - } + for (; rs < RTW_RATE_SECTION_MAX; rs++) + rtw_phy_set_tx_power_index_by_rs(rtwdev, ch, path, rs); } -void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum, - u32 regaddr, u32 bitmask, u32 data) +void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel) { - struct rtw_dev *rtwdev = adapter; + struct rtw_chip_info *chip = rtwdev->chip; struct rtw_hal *hal = &rtwdev->hal; - u8 rate_num = 0; - u8 rate; - u8 rates[RTW_RF_PATH_MAX] = {0}; - s8 offset; - s8 pwr_by_rate[RTW_RF_PATH_MAX] = {0}; - int i; + u8 path; - phy_get_rate_values_of_txpwr_by_rate(rtwdev, regaddr, bitmask, data, - rates, pwr_by_rate, &rate_num); + mutex_lock(&hal->tx_power_mutex); - if (WARN_ON(rfpath >= RTW_RF_PATH_MAX || - (band != PHY_BAND_2G && band != PHY_BAND_5G) || - rate_num > RTW_RF_PATH_MAX)) - return; + for (path = 0; path < hal->rf_path_num; path++) + rtw_phy_set_tx_power_level_by_path(rtwdev, channel, path); - for (i = 0; i < rate_num; i++) { - offset = pwr_by_rate[i]; - rate = rates[i]; - if (band == PHY_BAND_2G) - hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset; - else if (band == PHY_BAND_5G) - hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; - else - continue; - } + chip->ops->set_tx_power_index(rtwdev); + mutex_unlock(&hal->tx_power_mutex); } -static -void phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, - u8 rs, u8 size, u8 *rates) +static void +rtw_phy_tx_power_by_rate_config_by_path(struct rtw_hal *hal, u8 path, + u8 rs, u8 size, u8 *rates) { u8 rate; u8 base_idx, rate_idx; @@ -1574,36 +1747,35 @@ void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal) u8 path; for (path = 0; path < RTW_RF_PATH_MAX; path++) { - phy_tx_power_by_rate_config_by_path(hal, path, + rtw_phy_tx_power_by_rate_config_by_path(hal, path, RTW_RATE_SECTION_CCK, rtw_cck_size, rtw_cck_rates); - phy_tx_power_by_rate_config_by_path(hal, path, + rtw_phy_tx_power_by_rate_config_by_path(hal, path, RTW_RATE_SECTION_OFDM, rtw_ofdm_size, rtw_ofdm_rates); - phy_tx_power_by_rate_config_by_path(hal, path, + rtw_phy_tx_power_by_rate_config_by_path(hal, path, RTW_RATE_SECTION_HT_1S, rtw_ht_1s_size, rtw_ht_1s_rates); - phy_tx_power_by_rate_config_by_path(hal, path, + rtw_phy_tx_power_by_rate_config_by_path(hal, path, RTW_RATE_SECTION_HT_2S, rtw_ht_2s_size, rtw_ht_2s_rates); - phy_tx_power_by_rate_config_by_path(hal, path, + rtw_phy_tx_power_by_rate_config_by_path(hal, path, RTW_RATE_SECTION_VHT_1S, rtw_vht_1s_size, rtw_vht_1s_rates); - phy_tx_power_by_rate_config_by_path(hal, path, + rtw_phy_tx_power_by_rate_config_by_path(hal, path, RTW_RATE_SECTION_VHT_2S, rtw_vht_2s_size, rtw_vht_2s_rates); } } static void -phy_tx_power_limit_config(struct rtw_hal *hal, u8 regd, u8 bw, u8 rs) +__rtw_phy_tx_power_limit_config(struct rtw_hal *hal, u8 regd, u8 bw, u8 rs) { - s8 base, orig; + s8 base; u8 ch; for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++) { base = hal->tx_pwr_by_rate_base_2g[0][rs]; - orig = hal->tx_pwr_limit_2g[regd][bw][rs][ch]; hal->tx_pwr_limit_2g[regd][bw][rs][ch] -= base; } @@ -1617,98 +1789,34 @@ void rtw_phy_tx_power_limit_config(struct rtw_hal *hal) { u8 regd, bw, rs; + /* default at channel 1 */ + hal->cch_by_bw[RTW_CHANNEL_WIDTH_20] = 1; + for (regd = 0; regd < RTW_REGD_MAX; regd++) for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) - phy_tx_power_limit_config(hal, regd, bw, rs); -} - -static s8 get_tx_power_limit(struct rtw_hal *hal, u8 bw, u8 rs, u8 ch, u8 regd) -{ - if (regd > RTW_REGD_WW) - return RTW_MAX_POWER_INDEX; - - return hal->tx_pwr_limit_2g[regd][bw][rs][ch]; -} - -s8 phy_get_tx_power_limit(struct rtw_dev *rtwdev, u8 band, - enum rtw_bandwidth bw, u8 rf_path, - u8 rate, u8 channel, u8 regd) -{ - struct rtw_hal *hal = &rtwdev->hal; - s8 power_limit; - u8 rs; - int ch_idx; - - if (rate >= DESC_RATE1M && rate <= DESC_RATE11M) - rs = RTW_RATE_SECTION_CCK; - else if (rate >= DESC_RATE6M && rate <= DESC_RATE54M) - rs = RTW_RATE_SECTION_OFDM; - else if (rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS7) - rs = RTW_RATE_SECTION_HT_1S; - else if (rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) - rs = RTW_RATE_SECTION_HT_2S; - else if (rate >= DESC_RATEVHT1SS_MCS0 && rate <= DESC_RATEVHT1SS_MCS9) - rs = RTW_RATE_SECTION_VHT_1S; - else if (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9) - rs = RTW_RATE_SECTION_VHT_2S; - else - goto err; - - ch_idx = rtw_channel_to_idx(band, channel); - if (ch_idx < 0) - goto err; - - power_limit = get_tx_power_limit(hal, bw, rs, ch_idx, regd); - - return power_limit; - -err: - WARN(1, "invalid arguments, band=%d, bw=%d, path=%d, rate=%d, ch=%d\n", - band, bw, rf_path, rate, channel); - return RTW_MAX_POWER_INDEX; + __rtw_phy_tx_power_limit_config(hal, regd, bw, rs); } -void phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band, - u8 bw, u8 rs, u8 ch, s8 pwr_limit) +static void rtw_phy_init_tx_power_limit(struct rtw_dev *rtwdev, + u8 regd, u8 bw, u8 rs) { struct rtw_hal *hal = &rtwdev->hal; - int ch_idx; - - pwr_limit = clamp_t(s8, pwr_limit, - -RTW_MAX_POWER_INDEX, RTW_MAX_POWER_INDEX); - ch_idx = rtw_channel_to_idx(band, ch); - - if (regd >= RTW_REGD_MAX || bw >= RTW_CHANNEL_WIDTH_MAX || - rs >= RTW_RATE_SECTION_MAX || ch_idx < 0) { - WARN(1, - "wrong txpwr_lmt regd=%u, band=%u bw=%u, rs=%u, ch_idx=%u, pwr_limit=%d\n", - regd, band, bw, rs, ch_idx, pwr_limit); - return; - } - - if (band == PHY_BAND_2G) - hal->tx_pwr_limit_2g[regd][bw][rs][ch_idx] = pwr_limit; - else if (band == PHY_BAND_5G) - hal->tx_pwr_limit_5g[regd][bw][rs][ch_idx] = pwr_limit; -} - -static -void rtw_hw_tx_power_limit_init(struct rtw_hal *hal, u8 regd, u8 bw, u8 rs) -{ + s8 max_power_index = (s8)rtwdev->chip->max_power_index; u8 ch; /* 2.4G channels */ for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_2G; ch++) - hal->tx_pwr_limit_2g[regd][bw][rs][ch] = RTW_MAX_POWER_INDEX; + hal->tx_pwr_limit_2g[regd][bw][rs][ch] = max_power_index; /* 5G channels */ for (ch = 0; ch < RTW_MAX_CHANNEL_NUM_5G; ch++) - hal->tx_pwr_limit_5g[regd][bw][rs][ch] = RTW_MAX_POWER_INDEX; + hal->tx_pwr_limit_5g[regd][bw][rs][ch] = max_power_index; } -void rtw_hw_init_tx_power(struct rtw_hal *hal) +void rtw_phy_init_tx_power(struct rtw_dev *rtwdev) { + struct rtw_hal *hal = &rtwdev->hal; u8 regd, path, rate, rs, bw; /* init tx power by rate offset */ @@ -1723,5 +1831,6 @@ void rtw_hw_init_tx_power(struct rtw_hal *hal) for (regd = 0; regd < RTW_REGD_MAX; regd++) for (bw = 0; bw < RTW_CHANNEL_WIDTH_MAX; bw++) for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) - rtw_hw_tx_power_limit_init(hal, regd, bw, rs); + rtw_phy_init_tx_power_limit(rtwdev, regd, bw, + rs); } diff --git a/drivers/net/wireless/realtek/rtw88/phy.h b/drivers/net/wireless/realtek/rtw88/phy.h index ec03a2051e52..7c8eb732b13c 100644 --- a/drivers/net/wireless/realtek/rtw88/phy.h +++ b/drivers/net/wireless/realtek/rtw88/phy.h @@ -27,11 +27,6 @@ bool rtw_phy_write_rf_reg(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, u32 addr, u32 mask, u32 data); bool rtw_phy_write_rf_reg_mix(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, u32 addr, u32 mask, u32 data); -void phy_store_tx_power_by_rate(void *adapter, u32 band, u32 rfpath, u32 txnum, - u32 regaddr, u32 bitmask, u32 data); -void phy_set_tx_power_limit(struct rtw_dev *rtwdev, u8 regd, u8 band, - u8 bw, u8 rs, u8 ch, s8 pwr_limit); -void phy_set_tx_power_index_by_rs(void *adapter, u8 ch, u8 path, u8 rs); void rtw_phy_setup_phy_cond(struct rtw_dev *rtwdev, u32 pkg); void rtw_parse_tbl_phy_cond(struct rtw_dev *rtwdev, const struct rtw_table *tbl); void rtw_parse_tbl_bb_pg(struct rtw_dev *rtwdev, const struct rtw_table *tbl); @@ -44,7 +39,7 @@ void rtw_phy_cfg_bb(struct rtw_dev *rtwdev, const struct rtw_table *tbl, u32 addr, u32 data); void rtw_phy_cfg_rf(struct rtw_dev *rtwdev, const struct rtw_table *tbl, u32 addr, u32 data); -void rtw_hw_init_tx_power(struct rtw_hal *hal); +void rtw_phy_init_tx_power(struct rtw_dev *rtwdev); void rtw_phy_load_tables(struct rtw_dev *rtwdev); void rtw_phy_set_tx_power_level(struct rtw_dev *rtwdev, u8 channel); void rtw_phy_tx_power_by_rate_config(struct rtw_hal *hal); @@ -110,6 +105,17 @@ static inline int rtw_check_supported_rfe(struct rtw_dev *rtwdev) void rtw_phy_dig_write(struct rtw_dev *rtwdev, u8 igi); +struct rtw_power_params { + u8 pwr_base; + s8 pwr_offset; + s8 pwr_limit; +}; + +void +rtw_get_tx_power_params(struct rtw_dev *rtwdev, u8 path, + u8 rate, u8 bw, u8 ch, u8 regd, + struct rtw_power_params *pwr_param); + #define MASKBYTE0 0xff #define MASKBYTE1 0xff00 #define MASKBYTE2 0xff0000 diff --git a/drivers/net/wireless/realtek/rtw88/regd.c b/drivers/net/wireless/realtek/rtw88/regd.c index e7750a833a8e..69744dd65968 100644 --- a/drivers/net/wireless/realtek/rtw88/regd.c +++ b/drivers/net/wireless/realtek/rtw88/regd.c @@ -21,19 +21,19 @@ static const struct rtw_regulatory rtw_defined_chplan = static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("AD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("AE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("AE", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("AF", RTW_CHPLAN_ETSI1_ETSI4, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("AG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("AG", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("AI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("AL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("AM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("AN", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("AN", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("AO", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("AQ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("AR", RTW_CHPLAN_FCC2_FCC7, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("AS", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("AT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("AU", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("AU", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA), COUNTRY_CHPLAN_ENT("AW", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("AZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), @@ -42,31 +42,34 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("BE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("BH", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("BH", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BJ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("BM", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("BN", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BO", RTW_CHPLAN_WORLD_FCC7, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("BR", RTW_CHPLAN_FCC2_FCC1, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("BS", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), - COUNTRY_CHPLAN_ENT("BW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("BT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("BV", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("BW", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BY", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("BZ", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), - COUNTRY_CHPLAN_ENT("CA", RTW_CHPLAN_IC1_IC2, RTW_REGD_FCC), + COUNTRY_CHPLAN_ENT("CA", RTW_CHPLAN_IC1_IC2, RTW_REGD_IC), COUNTRY_CHPLAN_ENT("CC", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("CI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("CI", RTW_CHPLAN_ETSI1_ETSI4, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("CL", RTW_CHPLAN_WORLD_CHILE1, RTW_REGD_FCC), + COUNTRY_CHPLAN_ENT("CL", RTW_CHPLAN_WORLD_CHILE1, RTW_REGD_CHILE), COUNTRY_CHPLAN_ENT("CM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CN", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CO", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("CR", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("CV", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("CX", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("CX", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA), COUNTRY_CHPLAN_ENT("CY", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("CZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("DE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), @@ -90,7 +93,7 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("FR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("GA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("GB", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("GD", RTW_CHPLAN_FCC1_FCC7, RTW_REGD_FCC), + COUNTRY_CHPLAN_ENT("GD", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("GE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("GF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("GG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), @@ -107,8 +110,8 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("GU", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("GW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("GY", RTW_CHPLAN_FCC1_NCC3, RTW_REGD_FCC), - COUNTRY_CHPLAN_ENT("HK", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("HM", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("HK", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("HM", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA), COUNTRY_CHPLAN_ENT("HN", RTW_CHPLAN_WORLD_FCC5, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("HR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("HT", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), @@ -118,20 +121,22 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("IL", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("IM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("IN", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("IO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("IQ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("IR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("IS", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("IT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("JE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("JM", RTW_CHPLAN_WORLD_ETSI10, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("JM", RTW_CHPLAN_WORLD_FCC5, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("JO", RTW_CHPLAN_WORLD_ETSI8, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("JP", RTW_CHPLAN_MKK1_MKK1, RTW_REGD_MKK), COUNTRY_CHPLAN_ENT("KE", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("KG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("KH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("KI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("KM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("KN", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), - COUNTRY_CHPLAN_ENT("KR", RTW_CHPLAN_KCC1_KCC2, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("KR", RTW_CHPLAN_KCC1_KCC3, RTW_REGD_KCC), COUNTRY_CHPLAN_ENT("KW", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("KY", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("KZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), @@ -157,7 +162,7 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("ML", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("MM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("MN", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("MO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("MO", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("MP", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("MQ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("MR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), @@ -167,26 +172,26 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("MV", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("MW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("MX", RTW_CHPLAN_FCC2_FCC7, RTW_REGD_FCC), - COUNTRY_CHPLAN_ENT("MY", RTW_CHPLAN_WORLD_ETSI20, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("MY", RTW_CHPLAN_WORLD_ETSI15, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("MZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("NA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("NC", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("NE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("NF", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("NF", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA), COUNTRY_CHPLAN_ENT("NG", RTW_CHPLAN_WORLD_ETSI20, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("NI", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("NL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("NO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("NP", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("NP", RTW_CHPLAN_WORLD_ETSI7, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("NR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("NU", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("NZ", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("NU", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA), + COUNTRY_CHPLAN_ENT("NZ", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA), COUNTRY_CHPLAN_ENT("OM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("PA", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("PE", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("PF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("PG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("PH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("PG", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("PH", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("PK", RTW_CHPLAN_WORLD_ETSI10, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("PL", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("PM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), @@ -194,17 +199,17 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("PT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("PW", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("PY", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), - COUNTRY_CHPLAN_ENT("QA", RTW_CHPLAN_WORLD_ETSI10, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("QA", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("RE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("RO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("RS", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("RU", RTW_CHPLAN_WORLD_ETSI14, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("RW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("SA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("SA", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("SB", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("SC", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("SE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("SG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("SG", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("SH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("SI", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("SJ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), @@ -222,14 +227,15 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("TD", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("TF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("TG", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("TH", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("TH", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("TJ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("TK", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("TK", RTW_CHPLAN_WORLD_ACMA1, RTW_REGD_ACMA), COUNTRY_CHPLAN_ENT("TM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("TN", RTW_CHPLAN_WORLD_ETSI6, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("TO", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("TR", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("TT", RTW_CHPLAN_ETSI1_ETSI4, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("TT", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), + COUNTRY_CHPLAN_ENT("TV", RTW_CHPLAN_ETSI1_NULL, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("TW", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("TZ", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("UA", RTW_CHPLAN_WORLD_ETSI3, RTW_REGD_ETSI), @@ -240,14 +246,15 @@ static const struct rtw_regulatory all_chplan_map[] = { COUNTRY_CHPLAN_ENT("VA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("VC", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("VE", RTW_CHPLAN_WORLD_FCC3, RTW_REGD_FCC), + COUNTRY_CHPLAN_ENT("VG", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("VI", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), - COUNTRY_CHPLAN_ENT("VN", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("VN", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("VU", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("WF", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("WS", RTW_CHPLAN_FCC2_FCC11, RTW_REGD_FCC), COUNTRY_CHPLAN_ENT("YE", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("YT", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), - COUNTRY_CHPLAN_ENT("ZA", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), + COUNTRY_CHPLAN_ENT("ZA", RTW_CHPLAN_WORLD_ETSI2, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("ZM", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), COUNTRY_CHPLAN_ENT("ZW", RTW_CHPLAN_WORLD_ETSI1, RTW_REGD_ETSI), }; diff --git a/drivers/net/wireless/realtek/rtw88/regd.h b/drivers/net/wireless/realtek/rtw88/regd.h index 7784bb6d3ba7..5d4578331788 100644 --- a/drivers/net/wireless/realtek/rtw88/regd.h +++ b/drivers/net/wireless/realtek/rtw88/regd.h @@ -8,6 +8,7 @@ #define IEEE80211_CHAN_NO_IBSS IEEE80211_CHAN_NO_IR #define IEEE80211_CHAN_PASSIVE_SCAN IEEE80211_CHAN_NO_IR enum rtw_chplan_id { + RTW_CHPLAN_ETSI1_NULL = 0x21, RTW_CHPLAN_WORLD_ETSI1 = 0x26, RTW_CHPLAN_MKK1_MKK1 = 0x27, RTW_CHPLAN_IC1_IC2 = 0x2B, @@ -15,6 +16,7 @@ enum rtw_chplan_id { RTW_CHPLAN_WORLD_FCC3 = 0x30, RTW_CHPLAN_WORLD_FCC5 = 0x32, RTW_CHPLAN_FCC1_FCC7 = 0x34, + RTW_CHPLAN_WORLD_ETSI2 = 0x35, RTW_CHPLAN_WORLD_ETSI3 = 0x36, RTW_CHPLAN_ETSI1_ETSI12 = 0x3D, RTW_CHPLAN_KCC1_KCC2 = 0x3E, @@ -24,10 +26,12 @@ enum rtw_chplan_id { RTW_CHPLAN_WORLD_ETSI6 = 0x47, RTW_CHPLAN_WORLD_ETSI7 = 0x48, RTW_CHPLAN_WORLD_ETSI8 = 0x49, + RTW_CHPLAN_KCC1_KCC3 = 0x4B, RTW_CHPLAN_WORLD_ETSI10 = 0x51, RTW_CHPLAN_WORLD_ETSI14 = 0x59, RTW_CHPLAN_FCC2_FCC7 = 0x61, RTW_CHPLAN_FCC2_FCC1 = 0x62, + RTW_CHPLAN_WORLD_ETSI15 = 0x63, RTW_CHPLAN_WORLD_FCC7 = 0x73, RTW_CHPLAN_FCC2_FCC17 = 0x74, RTW_CHPLAN_WORLD_ETSI20 = 0x75, diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c index b4f7242e5aa3..f6214ff20337 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c @@ -203,7 +203,7 @@ static void rtw8822c_dac_iq_offset(struct rtw_dev *rtwdev, u32 *vec, u32 *val) *val = t; } -static u32 rtw8822c_get_path_base_addr(u8 path) +static u32 rtw8822c_get_path_write_addr(u8 path) { u32 base_addr; @@ -222,6 +222,25 @@ static u32 rtw8822c_get_path_base_addr(u8 path) return base_addr; } +static u32 rtw8822c_get_path_read_addr(u8 path) +{ + u32 base_addr; + + switch (path) { + case RF_PATH_A: + base_addr = 0x2800; + break; + case RF_PATH_B: + base_addr = 0x4500; + break; + default: + WARN_ON(1); + return -1; + } + + return base_addr; +} + static bool rtw8822c_dac_iq_check(struct rtw_dev *rtwdev, u32 value) { bool ret = true; @@ -316,8 +335,6 @@ static void rtw8822c_dac_cal_rf_mode(struct rtw_dev *rtwdev, u32 iv[DACK_SN_8822C], qv[DACK_SN_8822C]; u32 rf_a, rf_b; - mdelay(10); - rf_a = rtw_read_rf(rtwdev, RF_PATH_A, 0x0, RFREG_MASK); rf_b = rtw_read_rf(rtwdev, RF_PATH_B, 0x0, RFREG_MASK); @@ -347,6 +364,7 @@ static void rtw8822c_dac_bb_setting(struct rtw_dev *rtwdev) static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev, u8 path, u32 *adc_ic, u32 *adc_qc) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; u32 ic = 0, qc = 0, temp = 0; u32 base_addr; u32 path_sel; @@ -354,7 +372,7 @@ static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev, rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK path(%d)\n", path); - base_addr = rtw8822c_get_path_base_addr(path); + base_addr = rtw8822c_get_path_write_addr(path); switch (path) { case RF_PATH_A: path_sel = 0xa0000; @@ -396,6 +414,7 @@ static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev, } temp = (ic & 0x3ff) | ((qc & 0x3ff) << 10); rtw_write32(rtwdev, base_addr + 0x68, temp); + dm_info->dack_adck[path] = temp; rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] ADCK 0x%08x=0x08%x\n", base_addr + 0x68, temp); /* check ADC DC offset */ @@ -422,10 +441,14 @@ static void rtw8822c_dac_cal_adc(struct rtw_dev *rtwdev, static void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path) { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; u32 base_addr; + u32 read_addr; - base_addr = rtw8822c_get_path_base_addr(path); + base_addr = rtw8822c_get_path_write_addr(path); + read_addr = rtw8822c_get_path_read_addr(path); + rtw_write32(rtwdev, base_addr + 0x68, dm_info->dack_adck[path]); rtw_write32(rtwdev, base_addr + 0x0c, 0xdff00220); if (path == RF_PATH_A) { rtw_write32(rtwdev, base_addr + 0x60, 0xf0040ff0); @@ -447,11 +470,13 @@ static void rtw8822c_dac_cal_step1(struct rtw_dev *rtwdev, u8 path) rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); mdelay(1); rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); - mdelay(20); rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); mdelay(20); + if (!check_hw_ready(rtwdev, read_addr + 0x08, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, read_addr + 0x34, 0x7fff80, 0xffff)) + rtw_err(rtwdev, "failed to wait for dack ready\n"); rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); - mdelay(20); + mdelay(1); rtw_write32(rtwdev, base_addr + 0xbc, 0x0008ff87); rtw_write32(rtwdev, 0x9b4, 0xdb6db600); rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c5); @@ -465,7 +490,7 @@ static void rtw8822c_dac_cal_step2(struct rtw_dev *rtwdev, u32 base_addr; u32 ic, qc, ic_in, qc_in; - base_addr = rtw8822c_get_path_base_addr(path); + base_addr = rtw8822c_get_path_write_addr(path); rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xf0000000, 0x0); rtw_write32_mask(rtwdev, base_addr + 0xc0, 0xf, 0x8); rtw_write32_mask(rtwdev, base_addr + 0xd8, 0xf0000000, 0x0); @@ -514,10 +539,12 @@ static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path, u32 *i_out, u32 *q_out) { u32 base_addr; + u32 read_addr; u32 ic, qc; u32 temp; - base_addr = rtw8822c_get_path_base_addr(path); + base_addr = rtw8822c_get_path_write_addr(path); + read_addr = rtw8822c_get_path_read_addr(path); ic = *ic_in; qc = *qc_in; @@ -542,11 +569,13 @@ static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path, rtw_write32(rtwdev, base_addr + 0xcc, 0x0a11fb89); mdelay(1); rtw_write32(rtwdev, base_addr + 0xb8, 0x62000000); - mdelay(20); rtw_write32(rtwdev, base_addr + 0xd4, 0x62000000); mdelay(20); + if (!check_hw_ready(rtwdev, read_addr + 0x24, 0x07f80000, ic) || + !check_hw_ready(rtwdev, read_addr + 0x50, 0x07f80000, qc)) + rtw_err(rtwdev, "failed to write IQ vector to hardware\n"); rtw_write32(rtwdev, base_addr + 0xb8, 0x02000000); - mdelay(20); + mdelay(1); rtw_write32_mask(rtwdev, base_addr + 0xbc, 0xe, 0x3); rtw_write32(rtwdev, 0x9b4, 0xdb6db600); @@ -583,7 +612,7 @@ static void rtw8822c_dac_cal_step3(struct rtw_dev *rtwdev, u8 path, static void rtw8822c_dac_cal_step4(struct rtw_dev *rtwdev, u8 path) { - u32 base_addr = rtw8822c_get_path_base_addr(path); + u32 base_addr = rtw8822c_get_path_write_addr(path); rtw_write32(rtwdev, base_addr + 0x68, 0x0); rtw_write32(rtwdev, base_addr + 0x10, 0x02d508c4); @@ -591,6 +620,296 @@ static void rtw8822c_dac_cal_step4(struct rtw_dev *rtwdev, u8 path) rtw_write32_mask(rtwdev, base_addr + 0x30, BIT(30), 0x1); } +static void rtw8822c_dac_cal_backup_vec(struct rtw_dev *rtwdev, + u8 path, u8 vec, u32 w_addr, u32 r_addr) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u16 val; + u32 i; + + if (WARN_ON(vec >= 2)) + return; + + for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { + rtw_write32_mask(rtwdev, w_addr, 0xf0000000, i); + val = (u16)rtw_read32_mask(rtwdev, r_addr, 0x7fc0000); + dm_info->dack_msbk[path][vec][i] = val; + } +} + +static void rtw8822c_dac_cal_backup_path(struct rtw_dev *rtwdev, u8 path) +{ + u32 w_off = 0x1c; + u32 r_off = 0x2c; + u32 w_addr, r_addr; + + if (WARN_ON(path >= 2)) + return; + + /* backup I vector */ + w_addr = rtw8822c_get_path_write_addr(path) + 0xb0; + r_addr = rtw8822c_get_path_read_addr(path) + 0x10; + rtw8822c_dac_cal_backup_vec(rtwdev, path, 0, w_addr, r_addr); + + /* backup Q vector */ + w_addr = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; + r_addr = rtw8822c_get_path_read_addr(path) + 0x10 + r_off; + rtw8822c_dac_cal_backup_vec(rtwdev, path, 1, w_addr, r_addr); +} + +static void rtw8822c_dac_cal_backup_dck(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 val; + + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_A][0][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_I_1, 0xf); + dm_info->dack_dck[RF_PATH_A][0][1] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_A][1][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKA_Q_1, 0xf); + dm_info->dack_dck[RF_PATH_A][1][1] = val; + + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_B][0][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_I_1, 0xf); + dm_info->dack_dck[RF_PATH_B][1][0] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000); + dm_info->dack_dck[RF_PATH_B][0][1] = val; + val = (u8)rtw_read32_mask(rtwdev, REG_DCKB_Q_1, 0xf); + dm_info->dack_dck[RF_PATH_B][1][1] = val; +} + +static void rtw8822c_dac_cal_backup(struct rtw_dev *rtwdev) +{ + u32 temp[3]; + + temp[0] = rtw_read32(rtwdev, 0x1860); + temp[1] = rtw_read32(rtwdev, 0x4160); + temp[2] = rtw_read32(rtwdev, 0x9b4); + + /* set clock */ + rtw_write32(rtwdev, 0x9b4, 0xdb66db00); + + /* backup path-A I/Q */ + rtw_write32_clr(rtwdev, 0x1830, BIT(30)); + rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); + rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_A); + + /* backup path-B I/Q */ + rtw_write32_clr(rtwdev, 0x4130, BIT(30)); + rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); + rtw8822c_dac_cal_backup_path(rtwdev, RF_PATH_B); + + rtw8822c_dac_cal_backup_dck(rtwdev); + rtw_write32_set(rtwdev, 0x1830, BIT(30)); + rtw_write32_set(rtwdev, 0x4130, BIT(30)); + + rtw_write32(rtwdev, 0x1860, temp[0]); + rtw_write32(rtwdev, 0x4160, temp[1]); + rtw_write32(rtwdev, 0x9b4, temp[2]); +} + +static void rtw8822c_dac_cal_restore_dck(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u8 val; + + rtw_write32_set(rtwdev, REG_DCKA_I_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_A][0][0]; + rtw_write32_mask(rtwdev, REG_DCKA_I_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_A][0][1]; + rtw_write32_mask(rtwdev, REG_DCKA_I_1, 0xf, val); + + rtw_write32_set(rtwdev, REG_DCKA_Q_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_A][1][0]; + rtw_write32_mask(rtwdev, REG_DCKA_Q_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_A][1][1]; + rtw_write32_mask(rtwdev, REG_DCKA_Q_1, 0xf, val); + + rtw_write32_set(rtwdev, REG_DCKB_I_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_B][0][0]; + rtw_write32_mask(rtwdev, REG_DCKB_I_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_B][0][1]; + rtw_write32_mask(rtwdev, REG_DCKB_I_1, 0xf, val); + + rtw_write32_set(rtwdev, REG_DCKB_Q_0, BIT(19)); + val = dm_info->dack_dck[RF_PATH_B][1][0]; + rtw_write32_mask(rtwdev, REG_DCKB_Q_0, 0xf0000000, val); + val = dm_info->dack_dck[RF_PATH_B][1][1]; + rtw_write32_mask(rtwdev, REG_DCKB_Q_1, 0xf, val); +} + +static void rtw8822c_dac_cal_restore_prepare(struct rtw_dev *rtwdev) +{ + rtw_write32(rtwdev, 0x9b4, 0xdb66db00); + + rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x0); + rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x0); + rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x0); + rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x0); + + rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x0); + rtw_write32_mask(rtwdev, 0x1860, 0xfc000000, 0x3c); + rtw_write32_mask(rtwdev, 0x18b4, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x18d0, BIT(0), 0x1); + + rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x0); + rtw_write32_mask(rtwdev, 0x4160, 0xfc000000, 0x3c); + rtw_write32_mask(rtwdev, 0x41b4, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x41d0, BIT(0), 0x1); + + rtw_write32_mask(rtwdev, 0x18b0, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x18c0, BIT(14), 0x0); + rtw_write32_mask(rtwdev, 0x18cc, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x18dc, BIT(14), 0x0); + + rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x18b0, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x18cc, BIT(0), 0x1); + + rtw8822c_dac_cal_restore_dck(rtwdev); + + rtw_write32_mask(rtwdev, 0x18c0, 0x38000, 0x7); + rtw_write32_mask(rtwdev, 0x18dc, 0x38000, 0x7); + rtw_write32_mask(rtwdev, 0x41c0, 0x38000, 0x7); + rtw_write32_mask(rtwdev, 0x41dc, 0x38000, 0x7); + + rtw_write32_mask(rtwdev, 0x18b8, BIT(26) | BIT(25), 0x1); + rtw_write32_mask(rtwdev, 0x18d4, BIT(26) | BIT(25), 0x1); + + rtw_write32_mask(rtwdev, 0x41b0, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x41c0, BIT(14), 0x0); + rtw_write32_mask(rtwdev, 0x41cc, 0xf00, 0x0); + rtw_write32_mask(rtwdev, 0x41dc, BIT(14), 0x0); + + rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x0); + rtw_write32_mask(rtwdev, 0x41b0, BIT(0), 0x1); + rtw_write32_mask(rtwdev, 0x41cc, BIT(0), 0x1); + + rtw_write32_mask(rtwdev, 0x41b8, BIT(26) | BIT(25), 0x1); + rtw_write32_mask(rtwdev, 0x41d4, BIT(26) | BIT(25), 0x1); +} + +static bool rtw8822c_dac_cal_restore_wait(struct rtw_dev *rtwdev, + u32 target_addr, u32 toggle_addr) +{ + u32 cnt = 0; + + do { + rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x0); + rtw_write32_mask(rtwdev, toggle_addr, BIT(26) | BIT(25), 0x2); + + if (rtw_read32_mask(rtwdev, target_addr, 0xf) == 0x6) + return true; + + } while (cnt++ < 100); + + return false; +} + +static bool rtw8822c_dac_cal_restore_path(struct rtw_dev *rtwdev, u8 path) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 w_off = 0x1c; + u32 r_off = 0x2c; + u32 w_i, r_i, w_q, r_q; + u32 value; + u32 i; + + w_i = rtw8822c_get_path_write_addr(path) + 0xb0; + r_i = rtw8822c_get_path_read_addr(path) + 0x08; + w_q = rtw8822c_get_path_write_addr(path) + 0xb0 + w_off; + r_q = rtw8822c_get_path_read_addr(path) + 0x08 + r_off; + + if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_i, w_i + 0x8)) + return false; + + for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); + value = dm_info->dack_msbk[path][0][i]; + rtw_write32_mask(rtwdev, w_i + 0x4, 0xff8, value); + rtw_write32_mask(rtwdev, w_i, 0xf0000000, i); + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x1); + } + + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(2), 0x0); + + if (!rtw8822c_dac_cal_restore_wait(rtwdev, r_q, w_q + 0x8)) + return false; + + for (i = 0; i < DACK_MSBK_BACKUP_NUM; i++) { + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); + value = dm_info->dack_msbk[path][1][i]; + rtw_write32_mask(rtwdev, w_q + 0x4, 0xff8, value); + rtw_write32_mask(rtwdev, w_q, 0xf0000000, i); + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x1); + } + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(2), 0x0); + + rtw_write32_mask(rtwdev, w_i + 0x8, BIT(26) | BIT(25), 0x0); + rtw_write32_mask(rtwdev, w_q + 0x8, BIT(26) | BIT(25), 0x0); + rtw_write32_mask(rtwdev, w_i + 0x4, BIT(0), 0x0); + rtw_write32_mask(rtwdev, w_q + 0x4, BIT(0), 0x0); + + return true; +} + +static bool __rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) +{ + if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_A)) + return false; + + if (!rtw8822c_dac_cal_restore_path(rtwdev, RF_PATH_B)) + return false; + + return true; +} + +static bool rtw8822c_dac_cal_restore(struct rtw_dev *rtwdev) +{ + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + u32 temp[3]; + + /* sample the first element for both path's IQ vector */ + if (dm_info->dack_msbk[RF_PATH_A][0][0] == 0 && + dm_info->dack_msbk[RF_PATH_A][1][0] == 0 && + dm_info->dack_msbk[RF_PATH_B][0][0] == 0 && + dm_info->dack_msbk[RF_PATH_B][1][0] == 0) + return false; + + temp[0] = rtw_read32(rtwdev, 0x1860); + temp[1] = rtw_read32(rtwdev, 0x4160); + temp[2] = rtw_read32(rtwdev, 0x9b4); + + rtw8822c_dac_cal_restore_prepare(rtwdev); + if (!check_hw_ready(rtwdev, 0x2808, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, 0x2834, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, 0x4508, 0x7fff80, 0xffff) || + !check_hw_ready(rtwdev, 0x4534, 0x7fff80, 0xffff)) + return false; + + if (!__rtw8822c_dac_cal_restore(rtwdev)) { + rtw_err(rtwdev, "failed to restore dack vectors\n"); + return false; + } + + rtw_write32_mask(rtwdev, 0x1830, BIT(30), 0x1); + rtw_write32_mask(rtwdev, 0x4130, BIT(30), 0x1); + rtw_write32(rtwdev, 0x1860, temp[0]); + rtw_write32(rtwdev, 0x4160, temp[1]); + rtw_write32_mask(rtwdev, 0x18b0, BIT(27), 0x1); + rtw_write32_mask(rtwdev, 0x18cc, BIT(27), 0x1); + rtw_write32_mask(rtwdev, 0x41b0, BIT(27), 0x1); + rtw_write32_mask(rtwdev, 0x41cc, BIT(27), 0x1); + rtw_write32(rtwdev, 0x9b4, temp[2]); + + return true; +} + static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev) { struct rtw_backup_info backup_rf[DACK_RF_8822C * DACK_PATH_8822C]; @@ -600,6 +919,11 @@ static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev) u32 ic_a = 0x0, qc_a = 0x0, ic_b = 0x0, qc_b = 0x0; u32 adc_ic_a = 0x0, adc_qc_a = 0x0, adc_ic_b = 0x0, adc_qc_b = 0x0; + if (rtw8822c_dac_cal_restore(rtwdev)) + return; + + /* not able to restore, do it */ + rtw8822c_dac_backup_reg(rtwdev, backup, backup_rf); rtw8822c_dac_bb_setting(rtwdev); @@ -644,6 +968,9 @@ static void rtw8822c_rf_dac_cal(struct rtw_dev *rtwdev) rtw8822c_dac_restore_reg(rtwdev, backup, backup_rf); + /* backup results to restore, saving a lot of time */ + rtw8822c_dac_cal_backup(rtwdev); + rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: ic=0x%x, qc=0x%x\n", ic_a, qc_a); rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path B: ic=0x%x, qc=0x%x\n", ic_b, qc_b); rtw_dbg(rtwdev, RTW_DBG_RFK, "[DACK] path A: i=0x%x, q=0x%x\n", i_a, q_a); @@ -1015,8 +1342,28 @@ static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_clr(rtwdev, REG_CCKTXONLY, BIT_BB_CCK_CHECK_EN); rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0xF); - rtw_write32_mask(rtwdev, REG_RXAGCCTL0, 0x1f0, 0x0); - rtw_write32_mask(rtwdev, REG_RXAGCCTL, 0x1f0, 0x0); + switch (bw) { + case RTW_CHANNEL_WIDTH_20: + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, + 0x5); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, + 0x5); + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x6); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x6); + break; + case RTW_CHANNEL_WIDTH_40: + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_CCK, + 0x4); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_CCK, + 0x4); + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x0); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x0); + break; + } if (channel == 13 || channel == 14) rtw_write32_mask(rtwdev, REG_SCOTRK, 0xfff, 0x969); else if (channel == 11 || channel == 12) @@ -1061,14 +1408,20 @@ static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_mask(rtwdev, REG_CCAMSK, 0x3F000000, 0x22); rtw_write32_mask(rtwdev, REG_TXDFIR0, 0x70, 0x3); if (channel >= 36 && channel <= 64) { - rtw_write32_mask(rtwdev, REG_RXAGCCTL0, 0x1f0, 0x1); - rtw_write32_mask(rtwdev, REG_RXAGCCTL, 0x1f0, 0x1); + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x1); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x1); } else if (channel >= 100 && channel <= 144) { - rtw_write32_mask(rtwdev, REG_RXAGCCTL0, 0x1f0, 0x2); - rtw_write32_mask(rtwdev, REG_RXAGCCTL, 0x1f0, 0x2); + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x2); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x2); } else if (channel >= 149) { - rtw_write32_mask(rtwdev, REG_RXAGCCTL0, 0x1f0, 0x3); - rtw_write32_mask(rtwdev, REG_RXAGCCTL, 0x1f0, 0x3); + rtw_write32_mask(rtwdev, REG_RXAGCCTL0, BITS_RXAGC_OFDM, + 0x3); + rtw_write32_mask(rtwdev, REG_RXAGCCTL, BITS_RXAGC_OFDM, + 0x3); } if (channel >= 36 && channel <= 51) @@ -1092,6 +1445,9 @@ static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x0); rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x7); rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x6); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); break; case RTW_CHANNEL_WIDTH_40: rtw_write32_mask(rtwdev, REG_CCKSB, BIT(4), @@ -1100,12 +1456,17 @@ static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, (primary_ch_idx | (primary_ch_idx << 4))); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x1); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); break; case RTW_CHANNEL_WIDTH_80: rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xf, 0xa); rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xc0, 0x0); rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xff00, (primary_ch_idx | (primary_ch_idx << 4))); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x6); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x1); break; case RTW_CHANNEL_WIDTH_5: rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); @@ -1113,6 +1474,9 @@ static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x1); rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x4); rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x4); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); break; case RTW_CHANNEL_WIDTH_10: rtw_write32_mask(rtwdev, REG_DFIRBW, 0x3FF0, 0x2AB); @@ -1120,6 +1484,9 @@ static void rtw8822c_set_channel_bb(struct rtw_dev *rtwdev, u8 channel, u8 bw, rtw_write32_mask(rtwdev, REG_TXBWCTL, 0xffc0, 0x2); rtw_write32_mask(rtwdev, REG_TXCLK, 0x700, 0x6); rtw_write32_mask(rtwdev, REG_TXCLK, 0x700000, 0x5); + rtw_write32_mask(rtwdev, REG_CCK_SOURCE, BIT_NBI_EN, 0x0); + rtw_write32_mask(rtwdev, REG_SBD, BITS_SUBTUNE, 0x1); + rtw_write32_mask(rtwdev, REG_PT_CHSMO, BIT_PT_OPT, 0x0); break; } } @@ -1451,13 +1818,30 @@ static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev) u32 cck_enable; u32 cck_fa_cnt; u32 ofdm_fa_cnt; - u32 ofdm_tx_counter; + u32 ofdm_fa_cnt1, ofdm_fa_cnt2, ofdm_fa_cnt3, ofdm_fa_cnt4, ofdm_fa_cnt5; + u16 parity_fail, rate_illegal, crc8_fail, mcs_fail, sb_search_fail, + fast_fsync, crc8_fail_vhta, mcs_fail_vht; cck_enable = rtw_read32(rtwdev, REG_ENCCK) & BIT_CCK_BLK_EN; cck_fa_cnt = rtw_read16(rtwdev, REG_CCK_FACNT); - ofdm_fa_cnt = rtw_read16(rtwdev, REG_OFDM_FACNT); - ofdm_tx_counter = rtw_read16(rtwdev, REG_OFDM_TXCNT); - ofdm_fa_cnt -= ofdm_tx_counter; + + ofdm_fa_cnt1 = rtw_read32(rtwdev, REG_OFDM_FACNT1); + ofdm_fa_cnt2 = rtw_read32(rtwdev, REG_OFDM_FACNT2); + ofdm_fa_cnt3 = rtw_read32(rtwdev, REG_OFDM_FACNT3); + ofdm_fa_cnt4 = rtw_read32(rtwdev, REG_OFDM_FACNT4); + ofdm_fa_cnt5 = rtw_read32(rtwdev, REG_OFDM_FACNT5); + + parity_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt1); + rate_illegal = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt2); + crc8_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt2); + crc8_fail_vhta = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt3); + mcs_fail = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt4); + mcs_fail_vht = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt4); + fast_fsync = FIELD_GET(GENMASK(15, 0), ofdm_fa_cnt5); + sb_search_fail = FIELD_GET(GENMASK(31, 16), ofdm_fa_cnt5); + + ofdm_fa_cnt = parity_fail + rate_illegal + crc8_fail + crc8_fail_vhta + + mcs_fail + mcs_fail_vht + fast_fsync + sb_search_fail; dm_info->cck_fa_cnt = cck_fa_cnt; dm_info->ofdm_fa_cnt = ofdm_fa_cnt; @@ -1468,8 +1852,12 @@ static void rtw8822c_false_alarm_statistics(struct rtw_dev *rtwdev) rtw_write32_mask(rtwdev, REG_CCANRX, BIT_CCK_FA_RST, 2); rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 0); rtw_write32_mask(rtwdev, REG_CCANRX, BIT_OFDM_FA_RST, 2); + + /* disable rx clk gating to reset counters */ + rtw_write32_clr(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); rtw_write32_set(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); rtw_write32_clr(rtwdev, REG_CNT_CTRL, BIT_ALL_CNT_RST); + rtw_write32_set(rtwdev, REG_RX_BREAK, BIT_COM_RX_GCK_EN); } static void rtw8822c_do_iqk(struct rtw_dev *rtwdev) diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.h b/drivers/net/wireless/realtek/rtw88/rtw8822c.h index d3bd9850baa0..5ee1de41504d 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h @@ -133,6 +133,8 @@ struct rtw8822c_efuse { #define REG_DYMPRITH 0x86c #define REG_DYMENTH0 0x870 #define REG_DYMENTH 0x874 +#define REG_SBD 0x88c +#define BITS_SUBTUNE GENMASK(15, 12) #define REG_DYMTHMIN 0x8a4 #define REG_TXBWCTL 0x9b0 #define REG_TXCLK 0x9b4 @@ -140,12 +142,20 @@ struct rtw8822c_efuse { #define REG_MRCM 0xc38 #define REG_AGCSWSH 0xc44 #define REG_ANTWTPD 0xc54 +#define REG_PT_CHSMO 0xcbc +#define BIT_PT_OPT BIT(21) #define REG_ORITXCODE 0x1800 #define REG_3WIRE 0x180c #define BIT_3WIRE_TX_EN BIT(0) #define BIT_3WIRE_RX_EN BIT(1) #define BIT_3WIRE_PI_ON BIT(28) #define REG_RXAGCCTL0 0x18ac +#define BITS_RXAGC_CCK GENMASK(15, 12) +#define BITS_RXAGC_OFDM GENMASK(8, 4) +#define REG_DCKA_I_0 0x18bc +#define REG_DCKA_I_1 0x18c0 +#define REG_DCKA_Q_0 0x18d8 +#define REG_DCKA_Q_1 0x18dc #define REG_CCKSB 0x1a00 #define REG_RXCCKSEL 0x1a04 #define REG_BGCTRL 0x1a14 @@ -164,11 +174,15 @@ struct rtw8822c_efuse { #define REG_TXF5 0x1aa0 #define REG_TXF6 0x1aac #define REG_TXF7 0x1ab0 +#define REG_CCK_SOURCE 0x1abc +#define BIT_NBI_EN BIT(30) #define REG_TXANT 0x1c28 #define REG_ENCCK 0x1c3c #define BIT_CCK_BLK_EN BIT(1) #define BIT_CCK_OFDM_BLK_EN (BIT(0) | BIT(1)) #define REG_CCAMSK 0x1c80 +#define REG_RX_BREAK 0x1d2c +#define BIT_COM_RX_GCK_EN BIT(31) #define REG_RXFNCTL 0x1d30 #define REG_RXIGI 0x1d70 #define REG_ENFN 0x1e24 @@ -178,9 +192,18 @@ struct rtw8822c_efuse { #define REG_CNT_CTRL 0x1eb4 #define BIT_ALL_CNT_RST BIT(25) #define REG_OFDM_FACNT 0x2d00 +#define REG_OFDM_FACNT1 0x2d04 +#define REG_OFDM_FACNT2 0x2d08 +#define REG_OFDM_FACNT3 0x2d0c +#define REG_OFDM_FACNT4 0x2d10 +#define REG_OFDM_FACNT5 0x2d20 #define REG_OFDM_TXCNT 0x2de0 #define REG_ORITXCODE2 0x4100 #define REG_3WIRE2 0x410c #define REG_RXAGCCTL 0x41ac +#define REG_DCKB_I_0 0x41bc +#define REG_DCKB_I_1 0x41c0 +#define REG_DCKB_Q_0 0x41d8 +#define REG_DCKB_Q_1 0x41dc #endif diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c index 49044f510c6c..18e609a69829 100644 --- a/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c +++ b/drivers/net/wireless/realtek/rtw88/rtw8822c_table.c @@ -9489,55 +9489,55 @@ static const u8 rtw8822c_txpwr_lmt_type0[] = { 0, 0, 1, 3, 13, 127, 2, 0, 1, 3, 13, 127, 0, 0, 1, 3, 14, 127, 2, 0, 1, 3, 14, 127, 0, 1, 0, 1, 36, 74, 2, 1, 0, 1, 36, 62, - 0, 1, 0, 1, 40, 80, 2, 1, 0, 1, 40, 62, - 0, 1, 0, 1, 44, 80, 2, 1, 0, 1, 44, 62, - 0, 1, 0, 1, 48, 80, 2, 1, 0, 1, 48, 62, - 0, 1, 0, 1, 52, 80, 2, 1, 0, 1, 52, 62, - 0, 1, 0, 1, 56, 80, 2, 1, 0, 1, 56, 62, - 0, 1, 0, 1, 60, 80, 2, 1, 0, 1, 60, 62, + 0, 1, 0, 1, 40, 76, 2, 1, 0, 1, 40, 62, + 0, 1, 0, 1, 44, 76, 2, 1, 0, 1, 44, 62, + 0, 1, 0, 1, 48, 76, 2, 1, 0, 1, 48, 62, + 0, 1, 0, 1, 52, 76, 2, 1, 0, 1, 52, 62, + 0, 1, 0, 1, 56, 76, 2, 1, 0, 1, 56, 62, + 0, 1, 0, 1, 60, 76, 2, 1, 0, 1, 60, 62, 0, 1, 0, 1, 64, 74, 2, 1, 0, 1, 64, 62, 0, 1, 0, 1, 100, 72, 2, 1, 0, 1, 100, 62, - 0, 1, 0, 1, 104, 80, 2, 1, 0, 1, 104, 62, - 0, 1, 0, 1, 108, 80, 2, 1, 0, 1, 108, 62, - 0, 1, 0, 1, 112, 80, 2, 1, 0, 1, 112, 62, - 0, 1, 0, 1, 116, 80, 2, 1, 0, 1, 116, 62, - 0, 1, 0, 1, 120, 80, 2, 1, 0, 1, 120, 62, - 0, 1, 0, 1, 124, 80, 2, 1, 0, 1, 124, 62, - 0, 1, 0, 1, 128, 80, 2, 1, 0, 1, 128, 62, - 0, 1, 0, 1, 132, 80, 2, 1, 0, 1, 132, 62, - 0, 1, 0, 1, 136, 80, 2, 1, 0, 1, 136, 62, + 0, 1, 0, 1, 104, 76, 2, 1, 0, 1, 104, 62, + 0, 1, 0, 1, 108, 76, 2, 1, 0, 1, 108, 62, + 0, 1, 0, 1, 112, 76, 2, 1, 0, 1, 112, 62, + 0, 1, 0, 1, 116, 76, 2, 1, 0, 1, 116, 62, + 0, 1, 0, 1, 120, 76, 2, 1, 0, 1, 120, 62, + 0, 1, 0, 1, 124, 76, 2, 1, 0, 1, 124, 62, + 0, 1, 0, 1, 128, 76, 2, 1, 0, 1, 128, 62, + 0, 1, 0, 1, 132, 76, 2, 1, 0, 1, 132, 62, + 0, 1, 0, 1, 136, 76, 2, 1, 0, 1, 136, 62, 0, 1, 0, 1, 140, 72, 2, 1, 0, 1, 140, 62, - 0, 1, 0, 1, 144, 80, 2, 1, 0, 1, 144, 127, - 0, 1, 0, 1, 149, 80, 2, 1, 0, 1, 149, 127, - 0, 1, 0, 1, 153, 80, 2, 1, 0, 1, 153, 127, - 0, 1, 0, 1, 157, 80, 2, 1, 0, 1, 157, 127, - 0, 1, 0, 1, 161, 80, 2, 1, 0, 1, 161, 127, - 0, 1, 0, 1, 165, 80, 2, 1, 0, 1, 165, 127, + 0, 1, 0, 1, 144, 76, 2, 1, 0, 1, 144, 127, + 0, 1, 0, 1, 149, 76, 2, 1, 0, 1, 149, -128, + 0, 1, 0, 1, 153, 76, 2, 1, 0, 1, 153, -128, + 0, 1, 0, 1, 157, 76, 2, 1, 0, 1, 157, -128, + 0, 1, 0, 1, 161, 76, 2, 1, 0, 1, 161, -128, + 0, 1, 0, 1, 165, 76, 2, 1, 0, 1, 165, -128, 0, 1, 0, 2, 36, 72, 2, 1, 0, 2, 36, 62, - 0, 1, 0, 2, 40, 80, 2, 1, 0, 2, 40, 62, - 0, 1, 0, 2, 44, 80, 2, 1, 0, 2, 44, 62, - 0, 1, 0, 2, 48, 80, 2, 1, 0, 2, 48, 62, - 0, 1, 0, 2, 52, 80, 2, 1, 0, 2, 52, 62, - 0, 1, 0, 2, 56, 80, 2, 1, 0, 2, 56, 62, - 0, 1, 0, 2, 60, 80, 2, 1, 0, 2, 60, 62, + 0, 1, 0, 2, 40, 76, 2, 1, 0, 2, 40, 62, + 0, 1, 0, 2, 44, 76, 2, 1, 0, 2, 44, 62, + 0, 1, 0, 2, 48, 76, 2, 1, 0, 2, 48, 62, + 0, 1, 0, 2, 52, 76, 2, 1, 0, 2, 52, 62, + 0, 1, 0, 2, 56, 76, 2, 1, 0, 2, 56, 62, + 0, 1, 0, 2, 60, 76, 2, 1, 0, 2, 60, 62, 0, 1, 0, 2, 64, 74, 2, 1, 0, 2, 64, 62, 0, 1, 0, 2, 100, 70, 2, 1, 0, 2, 100, 62, - 0, 1, 0, 2, 104, 80, 2, 1, 0, 2, 104, 62, - 0, 1, 0, 2, 108, 80, 2, 1, 0, 2, 108, 62, - 0, 1, 0, 2, 112, 80, 2, 1, 0, 2, 112, 62, - 0, 1, 0, 2, 116, 80, 2, 1, 0, 2, 116, 62, - 0, 1, 0, 2, 120, 80, 2, 1, 0, 2, 120, 62, - 0, 1, 0, 2, 124, 80, 2, 1, 0, 2, 124, 62, - 0, 1, 0, 2, 128, 80, 2, 1, 0, 2, 128, 62, - 0, 1, 0, 2, 132, 80, 2, 1, 0, 2, 132, 62, - 0, 1, 0, 2, 136, 80, 2, 1, 0, 2, 136, 62, + 0, 1, 0, 2, 104, 76, 2, 1, 0, 2, 104, 62, + 0, 1, 0, 2, 108, 76, 2, 1, 0, 2, 108, 62, + 0, 1, 0, 2, 112, 76, 2, 1, 0, 2, 112, 62, + 0, 1, 0, 2, 116, 76, 2, 1, 0, 2, 116, 62, + 0, 1, 0, 2, 120, 76, 2, 1, 0, 2, 120, 62, + 0, 1, 0, 2, 124, 76, 2, 1, 0, 2, 124, 62, + 0, 1, 0, 2, 128, 76, 2, 1, 0, 2, 128, 62, + 0, 1, 0, 2, 132, 76, 2, 1, 0, 2, 132, 62, + 0, 1, 0, 2, 136, 76, 2, 1, 0, 2, 136, 62, 0, 1, 0, 2, 140, 70, 2, 1, 0, 2, 140, 62, - 0, 1, 0, 2, 144, 80, 2, 1, 0, 2, 144, 127, - 0, 1, 0, 2, 149, 80, 2, 1, 0, 2, 149, 127, - 0, 1, 0, 2, 153, 80, 2, 1, 0, 2, 153, 127, - 0, 1, 0, 2, 157, 80, 2, 1, 0, 2, 157, 127, - 0, 1, 0, 2, 161, 80, 2, 1, 0, 2, 161, 127, - 0, 1, 0, 2, 165, 80, 2, 1, 0, 2, 165, 127, + 0, 1, 0, 2, 144, 76, 2, 1, 0, 2, 144, 127, + 0, 1, 0, 2, 149, 76, 2, 1, 0, 2, 149, -128, + 0, 1, 0, 2, 153, 76, 2, 1, 0, 2, 153, -128, + 0, 1, 0, 2, 157, 76, 2, 1, 0, 2, 157, -128, + 0, 1, 0, 2, 161, 76, 2, 1, 0, 2, 161, -128, + 0, 1, 0, 2, 165, 76, 2, 1, 0, 2, 165, -128, 0, 1, 0, 3, 36, 68, 2, 1, 0, 3, 36, 38, 0, 1, 0, 3, 40, 68, 2, 1, 0, 3, 40, 38, 0, 1, 0, 3, 44, 68, 2, 1, 0, 3, 44, 38, @@ -9558,23 +9558,23 @@ static const u8 rtw8822c_txpwr_lmt_type0[] = { 0, 1, 0, 3, 136, 68, 2, 1, 0, 3, 136, 38, 0, 1, 0, 3, 140, 60, 2, 1, 0, 3, 140, 38, 0, 1, 0, 3, 144, 68, 2, 1, 0, 3, 144, 127, - 0, 1, 0, 3, 149, 80, 2, 1, 0, 3, 149, 127, - 0, 1, 0, 3, 153, 80, 2, 1, 0, 3, 153, 127, - 0, 1, 0, 3, 157, 80, 2, 1, 0, 3, 157, 127, - 0, 1, 0, 3, 161, 80, 2, 1, 0, 3, 161, 127, - 0, 1, 0, 3, 165, 80, 2, 1, 0, 3, 165, 127, + 0, 1, 0, 3, 149, 76, 2, 1, 0, 3, 149, -128, + 0, 1, 0, 3, 153, 76, 2, 1, 0, 3, 153, -128, + 0, 1, 0, 3, 157, 76, 2, 1, 0, 3, 157, -128, + 0, 1, 0, 3, 161, 76, 2, 1, 0, 3, 161, -128, + 0, 1, 0, 3, 165, 76, 2, 1, 0, 3, 165, -128, 0, 1, 1, 2, 38, 66, 2, 1, 1, 2, 38, 64, 0, 1, 1, 2, 46, 72, 2, 1, 1, 2, 46, 64, 0, 1, 1, 2, 54, 72, 2, 1, 1, 2, 54, 64, 0, 1, 1, 2, 62, 64, 2, 1, 1, 2, 62, 64, 0, 1, 1, 2, 102, 58, 2, 1, 1, 2, 102, 64, - 0, 1, 1, 2, 110, 74, 2, 1, 1, 2, 110, 64, - 0, 1, 1, 2, 118, 74, 2, 1, 1, 2, 118, 64, - 0, 1, 1, 2, 126, 74, 2, 1, 1, 2, 126, 64, - 0, 1, 1, 2, 134, 74, 2, 1, 1, 2, 134, 64, - 0, 1, 1, 2, 142, 74, 2, 1, 1, 2, 142, 127, - 0, 1, 1, 2, 151, 74, 2, 1, 1, 2, 151, 127, - 0, 1, 1, 2, 159, 74, 2, 1, 1, 2, 159, 127, + 0, 1, 1, 2, 110, 72, 2, 1, 1, 2, 110, 64, + 0, 1, 1, 2, 118, 72, 2, 1, 1, 2, 118, 64, + 0, 1, 1, 2, 126, 72, 2, 1, 1, 2, 126, 64, + 0, 1, 1, 2, 134, 72, 2, 1, 1, 2, 134, 64, + 0, 1, 1, 2, 142, 72, 2, 1, 1, 2, 142, 127, + 0, 1, 1, 2, 151, 72, 2, 1, 1, 2, 151, -128, + 0, 1, 1, 2, 159, 72, 2, 1, 1, 2, 159, -128, 0, 1, 1, 3, 38, 60, 2, 1, 1, 3, 38, 40, 0, 1, 1, 3, 46, 68, 2, 1, 1, 3, 46, 40, 0, 1, 1, 3, 54, 68, 2, 1, 1, 3, 54, 40, @@ -9585,20 +9585,703 @@ static const u8 rtw8822c_txpwr_lmt_type0[] = { 0, 1, 1, 3, 126, 68, 2, 1, 1, 3, 126, 40, 0, 1, 1, 3, 134, 68, 2, 1, 1, 3, 134, 40, 0, 1, 1, 3, 142, 68, 2, 1, 1, 3, 142, 127, - 0, 1, 1, 3, 151, 74, 2, 1, 1, 3, 151, 127, - 0, 1, 1, 3, 159, 74, 2, 1, 1, 3, 159, 127, + 0, 1, 1, 3, 151, 72, 2, 1, 1, 3, 151, -128, + 0, 1, 1, 3, 159, 72, 2, 1, 1, 3, 159, -128, 0, 1, 2, 4, 42, 64, 2, 1, 2, 4, 42, 64, 0, 1, 2, 4, 58, 62, 2, 1, 2, 4, 58, 64, 0, 1, 2, 4, 106, 58, 2, 1, 2, 4, 106, 64, 0, 1, 2, 4, 122, 72, 2, 1, 2, 4, 122, 64, 0, 1, 2, 4, 138, 72, 2, 1, 2, 4, 138, 127, - 0, 1, 2, 4, 155, 72, 2, 1, 2, 4, 155, 127, + 0, 1, 2, 4, 155, 72, 2, 1, 2, 4, 155, -128, 0, 1, 2, 5, 42, 54, 2, 1, 2, 5, 42, 40, 0, 1, 2, 5, 58, 52, 2, 1, 2, 5, 58, 40, 0, 1, 2, 5, 106, 50, 2, 1, 2, 5, 106, 40, 0, 1, 2, 5, 122, 66, 2, 1, 2, 5, 122, 40, 0, 1, 2, 5, 138, 66, 2, 1, 2, 5, 138, 127, - 0, 1, 2, 5, 155, 62, 2, 1, 2, 5, 155, 127 + 0, 1, 2, 5, 155, 62, 2, 1, 2, 5, 155, -128, + 1, 0, 0, 0, 1, 68, 3, 0, 0, 0, 1, 72, + 4, 0, 0, 0, 1, 76, 5, 0, 0, 0, 1, 60, + 6, 0, 0, 0, 1, 72, 7, 0, 0, 0, 1, 60, + 8, 0, 0, 0, 1, 72, 1, 0, 0, 0, 2, 68, + 3, 0, 0, 0, 2, 72, 4, 0, 0, 0, 2, 76, + 5, 0, 0, 0, 2, 60, 6, 0, 0, 0, 2, 72, + 7, 0, 0, 0, 2, 60, 8, 0, 0, 0, 2, 72, + 1, 0, 0, 0, 3, 68, 3, 0, 0, 0, 3, 76, + 4, 0, 0, 0, 3, 76, 5, 0, 0, 0, 3, 60, + 6, 0, 0, 0, 3, 76, 7, 0, 0, 0, 3, 60, + 8, 0, 0, 0, 3, 76, 1, 0, 0, 0, 4, 68, + 3, 0, 0, 0, 4, 76, 4, 0, 0, 0, 4, 76, + 5, 0, 0, 0, 4, 60, 6, 0, 0, 0, 4, 76, + 7, 0, 0, 0, 4, 60, 8, 0, 0, 0, 4, 76, + 1, 0, 0, 0, 5, 68, 3, 0, 0, 0, 5, 76, + 4, 0, 0, 0, 5, 76, 5, 0, 0, 0, 5, 60, + 6, 0, 0, 0, 5, 76, 7, 0, 0, 0, 5, 60, + 8, 0, 0, 0, 5, 76, 1, 0, 0, 0, 6, 68, + 3, 0, 0, 0, 6, 76, 4, 0, 0, 0, 6, 76, + 5, 0, 0, 0, 6, 60, 6, 0, 0, 0, 6, 76, + 7, 0, 0, 0, 6, 60, 8, 0, 0, 0, 6, 76, + 1, 0, 0, 0, 7, 68, 3, 0, 0, 0, 7, 76, + 4, 0, 0, 0, 7, 76, 5, 0, 0, 0, 7, 60, + 6, 0, 0, 0, 7, 76, 7, 0, 0, 0, 7, 60, + 8, 0, 0, 0, 7, 76, 1, 0, 0, 0, 8, 68, + 3, 0, 0, 0, 8, 76, 4, 0, 0, 0, 8, 76, + 5, 0, 0, 0, 8, 60, 6, 0, 0, 0, 8, 76, + 7, 0, 0, 0, 8, 60, 8, 0, 0, 0, 8, 76, + 1, 0, 0, 0, 9, 68, 3, 0, 0, 0, 9, 76, + 4, 0, 0, 0, 9, 76, 5, 0, 0, 0, 9, 60, + 6, 0, 0, 0, 9, 76, 7, 0, 0, 0, 9, 60, + 8, 0, 0, 0, 9, 76, 1, 0, 0, 0, 10, 68, + 3, 0, 0, 0, 10, 72, 4, 0, 0, 0, 10, 76, + 5, 0, 0, 0, 10, 60, 6, 0, 0, 0, 10, 72, + 7, 0, 0, 0, 10, 60, 8, 0, 0, 0, 10, 72, + 1, 0, 0, 0, 11, 68, 3, 0, 0, 0, 11, 72, + 4, 0, 0, 0, 11, 76, 5, 0, 0, 0, 11, 60, + 6, 0, 0, 0, 11, 72, 7, 0, 0, 0, 11, 60, + 8, 0, 0, 0, 11, 72, 1, 0, 0, 0, 12, 68, + 3, 0, 0, 0, 12, 52, 4, 0, 0, 0, 12, 76, + 5, 0, 0, 0, 12, 60, 6, 0, 0, 0, 12, 52, + 7, 0, 0, 0, 12, 60, 8, 0, 0, 0, 12, 52, + 1, 0, 0, 0, 13, 68, 3, 0, 0, 0, 13, 48, + 4, 0, 0, 0, 13, 76, 5, 0, 0, 0, 13, 60, + 6, 0, 0, 0, 13, 48, 7, 0, 0, 0, 13, 60, + 8, 0, 0, 0, 13, 48, 1, 0, 0, 0, 14, 68, + 3, 0, 0, 0, 14, 127, 4, 0, 0, 0, 14, 127, + 5, 0, 0, 0, 14, 127, 6, 0, 0, 0, 14, 127, + 7, 0, 0, 0, 14, 127, 8, 0, 0, 0, 14, 127, + 1, 0, 0, 1, 1, 76, 3, 0, 0, 1, 1, 52, + 4, 0, 0, 1, 1, 76, 5, 0, 0, 1, 1, 60, + 6, 0, 0, 1, 1, 52, 7, 0, 0, 1, 1, 60, + 8, 0, 0, 1, 1, 52, 1, 0, 0, 1, 2, 76, + 3, 0, 0, 1, 2, 60, 4, 0, 0, 1, 2, 76, + 5, 0, 0, 1, 2, 60, 6, 0, 0, 1, 2, 60, + 7, 0, 0, 1, 2, 60, 8, 0, 0, 1, 2, 60, + 1, 0, 0, 1, 3, 76, 3, 0, 0, 1, 3, 64, + 4, 0, 0, 1, 3, 76, 5, 0, 0, 1, 3, 60, + 6, 0, 0, 1, 3, 64, 7, 0, 0, 1, 3, 60, + 8, 0, 0, 1, 3, 64, 1, 0, 0, 1, 4, 76, + 3, 0, 0, 1, 4, 68, 4, 0, 0, 1, 4, 76, + 5, 0, 0, 1, 4, 60, 6, 0, 0, 1, 4, 68, + 7, 0, 0, 1, 4, 60, 8, 0, 0, 1, 4, 68, + 1, 0, 0, 1, 5, 76, 3, 0, 0, 1, 5, 76, + 4, 0, 0, 1, 5, 76, 5, 0, 0, 1, 5, 60, + 6, 0, 0, 1, 5, 76, 7, 0, 0, 1, 5, 60, + 8, 0, 0, 1, 5, 76, 1, 0, 0, 1, 6, 76, + 3, 0, 0, 1, 6, 76, 4, 0, 0, 1, 6, 76, + 5, 0, 0, 1, 6, 60, 6, 0, 0, 1, 6, 76, + 7, 0, 0, 1, 6, 60, 8, 0, 0, 1, 6, 76, + 1, 0, 0, 1, 7, 76, 3, 0, 0, 1, 7, 76, + 4, 0, 0, 1, 7, 76, 5, 0, 0, 1, 7, 60, + 6, 0, 0, 1, 7, 76, 7, 0, 0, 1, 7, 60, + 8, 0, 0, 1, 7, 76, 1, 0, 0, 1, 8, 76, + 3, 0, 0, 1, 8, 68, 4, 0, 0, 1, 8, 76, + 5, 0, 0, 1, 8, 60, 6, 0, 0, 1, 8, 68, + 7, 0, 0, 1, 8, 60, 8, 0, 0, 1, 8, 68, + 1, 0, 0, 1, 9, 76, 3, 0, 0, 1, 9, 64, + 4, 0, 0, 1, 9, 76, 5, 0, 0, 1, 9, 60, + 6, 0, 0, 1, 9, 64, 7, 0, 0, 1, 9, 60, + 8, 0, 0, 1, 9, 64, 1, 0, 0, 1, 10, 76, + 3, 0, 0, 1, 10, 60, 4, 0, 0, 1, 10, 76, + 5, 0, 0, 1, 10, 60, 6, 0, 0, 1, 10, 60, + 7, 0, 0, 1, 10, 60, 8, 0, 0, 1, 10, 60, + 1, 0, 0, 1, 11, 76, 3, 0, 0, 1, 11, 52, + 4, 0, 0, 1, 11, 76, 5, 0, 0, 1, 11, 60, + 6, 0, 0, 1, 11, 52, 7, 0, 0, 1, 11, 60, + 8, 0, 0, 1, 11, 52, 1, 0, 0, 1, 12, 76, + 3, 0, 0, 1, 12, 40, 4, 0, 0, 1, 12, 76, + 5, 0, 0, 1, 12, 60, 6, 0, 0, 1, 12, 40, + 7, 0, 0, 1, 12, 60, 8, 0, 0, 1, 12, 40, + 1, 0, 0, 1, 13, 76, 3, 0, 0, 1, 13, 28, + 4, 0, 0, 1, 13, 70, 5, 0, 0, 1, 13, 60, + 6, 0, 0, 1, 13, 28, 7, 0, 0, 1, 13, 60, + 8, 0, 0, 1, 13, 28, 1, 0, 0, 1, 14, 127, + 3, 0, 0, 1, 14, 127, 4, 0, 0, 1, 14, 127, + 5, 0, 0, 1, 14, 127, 6, 0, 0, 1, 14, 127, + 7, 0, 0, 1, 14, 127, 8, 0, 0, 1, 14, 127, + 1, 0, 0, 2, 1, 76, 3, 0, 0, 2, 1, 52, + 4, 0, 0, 2, 1, 76, 5, 0, 0, 2, 1, 60, + 6, 0, 0, 2, 1, 52, 7, 0, 0, 2, 1, 60, + 8, 0, 0, 2, 1, 52, 1, 0, 0, 2, 2, 76, + 3, 0, 0, 2, 2, 60, 4, 0, 0, 2, 2, 76, + 5, 0, 0, 2, 2, 60, 6, 0, 0, 2, 2, 60, + 7, 0, 0, 2, 2, 60, 8, 0, 0, 2, 2, 60, + 1, 0, 0, 2, 3, 76, 3, 0, 0, 2, 3, 64, + 4, 0, 0, 2, 3, 76, 5, 0, 0, 2, 3, 60, + 6, 0, 0, 2, 3, 64, 7, 0, 0, 2, 3, 60, + 8, 0, 0, 2, 3, 64, 1, 0, 0, 2, 4, 76, + 3, 0, 0, 2, 4, 68, 4, 0, 0, 2, 4, 76, + 5, 0, 0, 2, 4, 60, 6, 0, 0, 2, 4, 68, + 7, 0, 0, 2, 4, 60, 8, 0, 0, 2, 4, 68, + 1, 0, 0, 2, 5, 76, 3, 0, 0, 2, 5, 76, + 4, 0, 0, 2, 5, 76, 5, 0, 0, 2, 5, 60, + 6, 0, 0, 2, 5, 76, 7, 0, 0, 2, 5, 60, + 8, 0, 0, 2, 5, 76, 1, 0, 0, 2, 6, 76, + 3, 0, 0, 2, 6, 76, 4, 0, 0, 2, 6, 76, + 5, 0, 0, 2, 6, 60, 6, 0, 0, 2, 6, 76, + 7, 0, 0, 2, 6, 60, 8, 0, 0, 2, 6, 76, + 1, 0, 0, 2, 7, 76, 3, 0, 0, 2, 7, 76, + 4, 0, 0, 2, 7, 76, 5, 0, 0, 2, 7, 60, + 6, 0, 0, 2, 7, 76, 7, 0, 0, 2, 7, 60, + 8, 0, 0, 2, 7, 76, 1, 0, 0, 2, 8, 76, + 3, 0, 0, 2, 8, 68, 4, 0, 0, 2, 8, 76, + 5, 0, 0, 2, 8, 60, 6, 0, 0, 2, 8, 68, + 7, 0, 0, 2, 8, 60, 8, 0, 0, 2, 8, 68, + 1, 0, 0, 2, 9, 76, 3, 0, 0, 2, 9, 64, + 4, 0, 0, 2, 9, 76, 5, 0, 0, 2, 9, 60, + 6, 0, 0, 2, 9, 64, 7, 0, 0, 2, 9, 60, + 8, 0, 0, 2, 9, 64, 1, 0, 0, 2, 10, 76, + 3, 0, 0, 2, 10, 60, 4, 0, 0, 2, 10, 76, + 5, 0, 0, 2, 10, 60, 6, 0, 0, 2, 10, 60, + 7, 0, 0, 2, 10, 60, 8, 0, 0, 2, 10, 60, + 1, 0, 0, 2, 11, 76, 3, 0, 0, 2, 11, 52, + 4, 0, 0, 2, 11, 76, 5, 0, 0, 2, 11, 60, + 6, 0, 0, 2, 11, 52, 7, 0, 0, 2, 11, 60, + 8, 0, 0, 2, 11, 52, 1, 0, 0, 2, 12, 76, + 3, 0, 0, 2, 12, 40, 4, 0, 0, 2, 12, 76, + 5, 0, 0, 2, 12, 60, 6, 0, 0, 2, 12, 40, + 7, 0, 0, 2, 12, 60, 8, 0, 0, 2, 12, 40, + 1, 0, 0, 2, 13, 76, 3, 0, 0, 2, 13, 28, + 4, 0, 0, 2, 13, 72, 5, 0, 0, 2, 13, 60, + 6, 0, 0, 2, 13, 28, 7, 0, 0, 2, 13, 60, + 8, 0, 0, 2, 13, 28, 1, 0, 0, 2, 14, 127, + 3, 0, 0, 2, 14, 127, 4, 0, 0, 2, 14, 127, + 5, 0, 0, 2, 14, 127, 6, 0, 0, 2, 14, 127, + 7, 0, 0, 2, 14, 127, 8, 0, 0, 2, 14, 127, + 1, 0, 0, 3, 1, 66, 3, 0, 0, 3, 1, 52, + 4, 0, 0, 3, 1, 68, 5, 0, 0, 3, 1, 36, + 6, 0, 0, 3, 1, 52, 7, 0, 0, 3, 1, 36, + 8, 0, 0, 3, 1, 52, 1, 0, 0, 3, 2, 66, + 3, 0, 0, 3, 2, 60, 4, 0, 0, 3, 2, 70, + 5, 0, 0, 3, 2, 36, 6, 0, 0, 3, 2, 60, + 7, 0, 0, 3, 2, 36, 8, 0, 0, 3, 2, 60, + 1, 0, 0, 3, 3, 66, 3, 0, 0, 3, 3, 64, + 4, 0, 0, 3, 3, 70, 5, 0, 0, 3, 3, 36, + 6, 0, 0, 3, 3, 64, 7, 0, 0, 3, 3, 36, + 8, 0, 0, 3, 3, 64, 1, 0, 0, 3, 4, 66, + 3, 0, 0, 3, 4, 68, 4, 0, 0, 3, 4, 70, + 5, 0, 0, 3, 4, 36, 6, 0, 0, 3, 4, 68, + 7, 0, 0, 3, 4, 36, 8, 0, 0, 3, 4, 68, + 1, 0, 0, 3, 5, 66, 3, 0, 0, 3, 5, 76, + 4, 0, 0, 3, 5, 70, 5, 0, 0, 3, 5, 36, + 6, 0, 0, 3, 5, 76, 7, 0, 0, 3, 5, 36, + 8, 0, 0, 3, 5, 76, 1, 0, 0, 3, 6, 66, + 3, 0, 0, 3, 6, 76, 4, 0, 0, 3, 6, 70, + 5, 0, 0, 3, 6, 36, 6, 0, 0, 3, 6, 76, + 7, 0, 0, 3, 6, 36, 8, 0, 0, 3, 6, 76, + 1, 0, 0, 3, 7, 66, 3, 0, 0, 3, 7, 76, + 4, 0, 0, 3, 7, 70, 5, 0, 0, 3, 7, 36, + 6, 0, 0, 3, 7, 76, 7, 0, 0, 3, 7, 36, + 8, 0, 0, 3, 7, 76, 1, 0, 0, 3, 8, 66, + 3, 0, 0, 3, 8, 68, 4, 0, 0, 3, 8, 70, + 5, 0, 0, 3, 8, 36, 6, 0, 0, 3, 8, 68, + 7, 0, 0, 3, 8, 36, 8, 0, 0, 3, 8, 68, + 1, 0, 0, 3, 9, 66, 3, 0, 0, 3, 9, 64, + 4, 0, 0, 3, 9, 70, 5, 0, 0, 3, 9, 36, + 6, 0, 0, 3, 9, 64, 7, 0, 0, 3, 9, 36, + 8, 0, 0, 3, 9, 64, 1, 0, 0, 3, 10, 66, + 3, 0, 0, 3, 10, 60, 4, 0, 0, 3, 10, 70, + 5, 0, 0, 3, 10, 36, 6, 0, 0, 3, 10, 60, + 7, 0, 0, 3, 10, 36, 8, 0, 0, 3, 10, 60, + 1, 0, 0, 3, 11, 66, 3, 0, 0, 3, 11, 52, + 4, 0, 0, 3, 11, 70, 5, 0, 0, 3, 11, 36, + 6, 0, 0, 3, 11, 52, 7, 0, 0, 3, 11, 36, + 8, 0, 0, 3, 11, 52, 1, 0, 0, 3, 12, 66, + 3, 0, 0, 3, 12, 40, 4, 0, 0, 3, 12, 70, + 5, 0, 0, 3, 12, 36, 6, 0, 0, 3, 12, 40, + 7, 0, 0, 3, 12, 36, 8, 0, 0, 3, 12, 40, + 1, 0, 0, 3, 13, 66, 3, 0, 0, 3, 13, 28, + 4, 0, 0, 3, 13, 62, 5, 0, 0, 3, 13, 36, + 6, 0, 0, 3, 13, 28, 7, 0, 0, 3, 13, 36, + 8, 0, 0, 3, 13, 28, 1, 0, 0, 3, 14, 127, + 3, 0, 0, 3, 14, 127, 4, 0, 0, 3, 14, 127, + 5, 0, 0, 3, 14, 127, 6, 0, 0, 3, 14, 127, + 7, 0, 0, 3, 14, 127, 8, 0, 0, 3, 14, 127, + 1, 0, 1, 2, 1, 127, 3, 0, 1, 2, 1, 127, + 4, 0, 1, 2, 1, 127, 5, 0, 1, 2, 1, 127, + 6, 0, 1, 2, 1, 127, 7, 0, 1, 2, 1, 127, + 8, 0, 1, 2, 1, 127, 1, 0, 1, 2, 2, 127, + 3, 0, 1, 2, 2, 127, 4, 0, 1, 2, 2, 127, + 5, 0, 1, 2, 2, 127, 6, 0, 1, 2, 2, 127, + 7, 0, 1, 2, 2, 127, 8, 0, 1, 2, 2, 127, + 1, 0, 1, 2, 3, 72, 3, 0, 1, 2, 3, 52, + 4, 0, 1, 2, 3, 72, 5, 0, 1, 2, 3, 60, + 6, 0, 1, 2, 3, 52, 7, 0, 1, 2, 3, 60, + 8, 0, 1, 2, 3, 52, 1, 0, 1, 2, 4, 72, + 3, 0, 1, 2, 4, 52, 4, 0, 1, 2, 4, 72, + 5, 0, 1, 2, 4, 60, 6, 0, 1, 2, 4, 52, + 7, 0, 1, 2, 4, 60, 8, 0, 1, 2, 4, 52, + 1, 0, 1, 2, 5, 72, 3, 0, 1, 2, 5, 60, + 4, 0, 1, 2, 5, 72, 5, 0, 1, 2, 5, 60, + 6, 0, 1, 2, 5, 60, 7, 0, 1, 2, 5, 60, + 8, 0, 1, 2, 5, 60, 1, 0, 1, 2, 6, 72, + 3, 0, 1, 2, 6, 64, 4, 0, 1, 2, 6, 72, + 5, 0, 1, 2, 6, 60, 6, 0, 1, 2, 6, 64, + 7, 0, 1, 2, 6, 60, 8, 0, 1, 2, 6, 64, + 1, 0, 1, 2, 7, 72, 3, 0, 1, 2, 7, 60, + 4, 0, 1, 2, 7, 72, 5, 0, 1, 2, 7, 60, + 6, 0, 1, 2, 7, 60, 7, 0, 1, 2, 7, 60, + 8, 0, 1, 2, 7, 60, 1, 0, 1, 2, 8, 72, + 3, 0, 1, 2, 8, 52, 4, 0, 1, 2, 8, 72, + 5, 0, 1, 2, 8, 60, 6, 0, 1, 2, 8, 52, + 7, 0, 1, 2, 8, 60, 8, 0, 1, 2, 8, 52, + 1, 0, 1, 2, 9, 72, 3, 0, 1, 2, 9, 52, + 4, 0, 1, 2, 9, 72, 5, 0, 1, 2, 9, 60, + 6, 0, 1, 2, 9, 52, 7, 0, 1, 2, 9, 60, + 8, 0, 1, 2, 9, 52, 1, 0, 1, 2, 10, 72, + 3, 0, 1, 2, 10, 40, 4, 0, 1, 2, 10, 72, + 5, 0, 1, 2, 10, 60, 6, 0, 1, 2, 10, 40, + 7, 0, 1, 2, 10, 60, 8, 0, 1, 2, 10, 40, + 1, 0, 1, 2, 11, 72, 3, 0, 1, 2, 11, 28, + 4, 0, 1, 2, 11, 70, 5, 0, 1, 2, 11, 60, + 6, 0, 1, 2, 11, 28, 7, 0, 1, 2, 11, 60, + 8, 0, 1, 2, 11, 28, 1, 0, 1, 2, 12, 127, + 3, 0, 1, 2, 12, 127, 4, 0, 1, 2, 12, 127, + 5, 0, 1, 2, 12, 127, 6, 0, 1, 2, 12, 127, + 7, 0, 1, 2, 12, 127, 8, 0, 1, 2, 12, 127, + 1, 0, 1, 2, 13, 127, 3, 0, 1, 2, 13, 127, + 4, 0, 1, 2, 13, 127, 5, 0, 1, 2, 13, 127, + 6, 0, 1, 2, 13, 127, 7, 0, 1, 2, 13, 127, + 8, 0, 1, 2, 13, 127, 1, 0, 1, 2, 14, 127, + 3, 0, 1, 2, 14, 127, 4, 0, 1, 2, 14, 127, + 5, 0, 1, 2, 14, 127, 6, 0, 1, 2, 14, 127, + 7, 0, 1, 2, 14, 127, 8, 0, 1, 2, 14, 127, + 1, 0, 1, 3, 1, 127, 3, 0, 1, 3, 1, 127, + 4, 0, 1, 3, 1, 127, 5, 0, 1, 3, 1, 127, + 6, 0, 1, 3, 1, 127, 7, 0, 1, 3, 1, 127, + 8, 0, 1, 3, 1, 127, 1, 0, 1, 3, 2, 127, + 3, 0, 1, 3, 2, 127, 4, 0, 1, 3, 2, 127, + 5, 0, 1, 3, 2, 127, 6, 0, 1, 3, 2, 127, + 7, 0, 1, 3, 2, 127, 8, 0, 1, 3, 2, 127, + 1, 0, 1, 3, 3, 66, 3, 0, 1, 3, 3, 48, + 4, 0, 1, 3, 3, 66, 5, 0, 1, 3, 3, 36, + 6, 0, 1, 3, 3, 48, 7, 0, 1, 3, 3, 36, + 8, 0, 1, 3, 3, 48, 1, 0, 1, 3, 4, 66, + 3, 0, 1, 3, 4, 48, 4, 0, 1, 3, 4, 70, + 5, 0, 1, 3, 4, 36, 6, 0, 1, 3, 4, 48, + 7, 0, 1, 3, 4, 36, 8, 0, 1, 3, 4, 48, + 1, 0, 1, 3, 5, 66, 3, 0, 1, 3, 5, 60, + 4, 0, 1, 3, 5, 70, 5, 0, 1, 3, 5, 36, + 6, 0, 1, 3, 5, 60, 7, 0, 1, 3, 5, 36, + 8, 0, 1, 3, 5, 60, 1, 0, 1, 3, 6, 66, + 3, 0, 1, 3, 6, 64, 4, 0, 1, 3, 6, 70, + 5, 0, 1, 3, 6, 36, 6, 0, 1, 3, 6, 64, + 7, 0, 1, 3, 6, 36, 8, 0, 1, 3, 6, 64, + 1, 0, 1, 3, 7, 66, 3, 0, 1, 3, 7, 60, + 4, 0, 1, 3, 7, 70, 5, 0, 1, 3, 7, 36, + 6, 0, 1, 3, 7, 60, 7, 0, 1, 3, 7, 36, + 8, 0, 1, 3, 7, 60, 1, 0, 1, 3, 8, 66, + 3, 0, 1, 3, 8, 52, 4, 0, 1, 3, 8, 70, + 5, 0, 1, 3, 8, 36, 6, 0, 1, 3, 8, 52, + 7, 0, 1, 3, 8, 36, 8, 0, 1, 3, 8, 52, + 1, 0, 1, 3, 9, 66, 3, 0, 1, 3, 9, 52, + 4, 0, 1, 3, 9, 70, 5, 0, 1, 3, 9, 36, + 6, 0, 1, 3, 9, 52, 7, 0, 1, 3, 9, 36, + 8, 0, 1, 3, 9, 52, 1, 0, 1, 3, 10, 66, + 3, 0, 1, 3, 10, 40, 4, 0, 1, 3, 10, 70, + 5, 0, 1, 3, 10, 36, 6, 0, 1, 3, 10, 40, + 7, 0, 1, 3, 10, 36, 8, 0, 1, 3, 10, 40, + 1, 0, 1, 3, 11, 66, 3, 0, 1, 3, 11, 26, + 4, 0, 1, 3, 11, 66, 5, 0, 1, 3, 11, 36, + 6, 0, 1, 3, 11, 26, 7, 0, 1, 3, 11, 36, + 8, 0, 1, 3, 11, 26, 1, 0, 1, 3, 12, 127, + 3, 0, 1, 3, 12, 127, 4, 0, 1, 3, 12, 127, + 5, 0, 1, 3, 12, 127, 6, 0, 1, 3, 12, 127, + 7, 0, 1, 3, 12, 127, 8, 0, 1, 3, 12, 127, + 1, 0, 1, 3, 13, 127, 3, 0, 1, 3, 13, 127, + 4, 0, 1, 3, 13, 127, 5, 0, 1, 3, 13, 127, + 6, 0, 1, 3, 13, 127, 7, 0, 1, 3, 13, 127, + 8, 0, 1, 3, 13, 127, 1, 0, 1, 3, 14, 127, + 3, 0, 1, 3, 14, 127, 4, 0, 1, 3, 14, 127, + 5, 0, 1, 3, 14, 127, 6, 0, 1, 3, 14, 127, + 7, 0, 1, 3, 14, 127, 8, 0, 1, 3, 14, 127, + 1, 1, 0, 1, 36, 60, 3, 1, 0, 1, 36, 62, + 4, 1, 0, 1, 36, 76, 5, 1, 0, 1, 36, 62, + 6, 1, 0, 1, 36, 64, 7, 1, 0, 1, 36, 54, + 8, 1, 0, 1, 36, 62, 1, 1, 0, 1, 40, 62, + 3, 1, 0, 1, 40, 62, 4, 1, 0, 1, 40, 76, + 5, 1, 0, 1, 40, 62, 6, 1, 0, 1, 40, 64, + 7, 1, 0, 1, 40, 54, 8, 1, 0, 1, 40, 62, + 1, 1, 0, 1, 44, 62, 3, 1, 0, 1, 44, 62, + 4, 1, 0, 1, 44, 76, 5, 1, 0, 1, 44, 62, + 6, 1, 0, 1, 44, 64, 7, 1, 0, 1, 44, 54, + 8, 1, 0, 1, 44, 62, 1, 1, 0, 1, 48, 62, + 3, 1, 0, 1, 48, 62, 4, 1, 0, 1, 48, 76, + 5, 1, 0, 1, 48, 62, 6, 1, 0, 1, 48, 64, + 7, 1, 0, 1, 48, 54, 8, 1, 0, 1, 48, 62, + 1, 1, 0, 1, 52, 62, 3, 1, 0, 1, 52, 64, + 4, 1, 0, 1, 52, 76, 5, 1, 0, 1, 52, 62, + 6, 1, 0, 1, 52, 76, 7, 1, 0, 1, 52, 54, + 8, 1, 0, 1, 52, 76, 1, 1, 0, 1, 56, 62, + 3, 1, 0, 1, 56, 64, 4, 1, 0, 1, 56, 76, + 5, 1, 0, 1, 56, 62, 6, 1, 0, 1, 56, 76, + 7, 1, 0, 1, 56, 54, 8, 1, 0, 1, 56, 76, + 1, 1, 0, 1, 60, 62, 3, 1, 0, 1, 60, 64, + 4, 1, 0, 1, 60, 76, 5, 1, 0, 1, 60, 62, + 6, 1, 0, 1, 60, 76, 7, 1, 0, 1, 60, 54, + 8, 1, 0, 1, 60, 76, 1, 1, 0, 1, 64, 60, + 3, 1, 0, 1, 64, 64, 4, 1, 0, 1, 64, 76, + 5, 1, 0, 1, 64, 62, 6, 1, 0, 1, 64, 74, + 7, 1, 0, 1, 64, 54, 8, 1, 0, 1, 64, 74, + 1, 1, 0, 1, 100, 76, 3, 1, 0, 1, 100, 72, + 4, 1, 0, 1, 100, 76, 5, 1, 0, 1, 100, 62, + 6, 1, 0, 1, 100, 72, 7, 1, 0, 1, 100, 54, + 8, 1, 0, 1, 100, 72, 1, 1, 0, 1, 104, 76, + 3, 1, 0, 1, 104, 76, 4, 1, 0, 1, 104, 76, + 5, 1, 0, 1, 104, 62, 6, 1, 0, 1, 104, 76, + 7, 1, 0, 1, 104, 54, 8, 1, 0, 1, 104, 76, + 1, 1, 0, 1, 108, 76, 3, 1, 0, 1, 108, 76, + 4, 1, 0, 1, 108, 76, 5, 1, 0, 1, 108, 62, + 6, 1, 0, 1, 108, 76, 7, 1, 0, 1, 108, 54, + 8, 1, 0, 1, 108, 76, 1, 1, 0, 1, 112, 76, + 3, 1, 0, 1, 112, 76, 4, 1, 0, 1, 112, 76, + 5, 1, 0, 1, 112, 62, 6, 1, 0, 1, 112, 76, + 7, 1, 0, 1, 112, 54, 8, 1, 0, 1, 112, 76, + 1, 1, 0, 1, 116, 76, 3, 1, 0, 1, 116, 76, + 4, 1, 0, 1, 116, 76, 5, 1, 0, 1, 116, 62, + 6, 1, 0, 1, 116, 76, 7, 1, 0, 1, 116, 54, + 8, 1, 0, 1, 116, 76, 1, 1, 0, 1, 120, 76, + 3, 1, 0, 1, 120, 127, 4, 1, 0, 1, 120, 76, + 5, 1, 0, 1, 120, 127, 6, 1, 0, 1, 120, 76, + 7, 1, 0, 1, 120, 54, 8, 1, 0, 1, 120, 76, + 1, 1, 0, 1, 124, 76, 3, 1, 0, 1, 124, 127, + 4, 1, 0, 1, 124, 76, 5, 1, 0, 1, 124, 127, + 6, 1, 0, 1, 124, 76, 7, 1, 0, 1, 124, 54, + 8, 1, 0, 1, 124, 76, 1, 1, 0, 1, 128, 76, + 3, 1, 0, 1, 128, 127, 4, 1, 0, 1, 128, 76, + 5, 1, 0, 1, 128, 127, 6, 1, 0, 1, 128, 76, + 7, 1, 0, 1, 128, 54, 8, 1, 0, 1, 128, 76, + 1, 1, 0, 1, 132, 76, 3, 1, 0, 1, 132, 76, + 4, 1, 0, 1, 132, 76, 5, 1, 0, 1, 132, 62, + 6, 1, 0, 1, 132, 76, 7, 1, 0, 1, 132, 54, + 8, 1, 0, 1, 132, 76, 1, 1, 0, 1, 136, 76, + 3, 1, 0, 1, 136, 76, 4, 1, 0, 1, 136, 76, + 5, 1, 0, 1, 136, 62, 6, 1, 0, 1, 136, 76, + 7, 1, 0, 1, 136, 127, 8, 1, 0, 1, 136, 76, + 1, 1, 0, 1, 140, 76, 3, 1, 0, 1, 140, 72, + 4, 1, 0, 1, 140, 76, 5, 1, 0, 1, 140, 62, + 6, 1, 0, 1, 140, 72, 7, 1, 0, 1, 140, 127, + 8, 1, 0, 1, 140, 72, 1, 1, 0, 1, 144, 127, + 3, 1, 0, 1, 144, 76, 4, 1, 0, 1, 144, 76, + 5, 1, 0, 1, 144, 127, 6, 1, 0, 1, 144, 76, + 7, 1, 0, 1, 144, 127, 8, 1, 0, 1, 144, 76, + 1, 1, 0, 1, 149, 127, 3, 1, 0, 1, 149, 76, + 4, 1, 0, 1, 149, 74, 5, 1, 0, 1, 149, 76, + 6, 1, 0, 1, 149, 76, 7, 1, 0, 1, 149, 54, + 8, 1, 0, 1, 149, 76, 1, 1, 0, 1, 153, 127, + 3, 1, 0, 1, 153, 76, 4, 1, 0, 1, 153, 74, + 5, 1, 0, 1, 153, 76, 6, 1, 0, 1, 153, 76, + 7, 1, 0, 1, 153, 54, 8, 1, 0, 1, 153, 76, + 1, 1, 0, 1, 157, 127, 3, 1, 0, 1, 157, 76, + 4, 1, 0, 1, 157, 74, 5, 1, 0, 1, 157, 76, + 6, 1, 0, 1, 157, 76, 7, 1, 0, 1, 157, 54, + 8, 1, 0, 1, 157, 76, 1, 1, 0, 1, 161, 127, + 3, 1, 0, 1, 161, 76, 4, 1, 0, 1, 161, 74, + 5, 1, 0, 1, 161, 76, 6, 1, 0, 1, 161, 76, + 7, 1, 0, 1, 161, 54, 8, 1, 0, 1, 161, 76, + 1, 1, 0, 1, 165, 127, 3, 1, 0, 1, 165, 76, + 4, 1, 0, 1, 165, 74, 5, 1, 0, 1, 165, 76, + 6, 1, 0, 1, 165, 76, 7, 1, 0, 1, 165, 54, + 8, 1, 0, 1, 165, 76, 1, 1, 0, 2, 36, 62, + 3, 1, 0, 2, 36, 62, 4, 1, 0, 2, 36, 76, + 5, 1, 0, 2, 36, 62, 6, 1, 0, 2, 36, 64, + 7, 1, 0, 2, 36, 54, 8, 1, 0, 2, 36, 62, + 1, 1, 0, 2, 40, 62, 3, 1, 0, 2, 40, 62, + 4, 1, 0, 2, 40, 76, 5, 1, 0, 2, 40, 62, + 6, 1, 0, 2, 40, 64, 7, 1, 0, 2, 40, 54, + 8, 1, 0, 2, 40, 62, 1, 1, 0, 2, 44, 62, + 3, 1, 0, 2, 44, 62, 4, 1, 0, 2, 44, 76, + 5, 1, 0, 2, 44, 62, 6, 1, 0, 2, 44, 64, + 7, 1, 0, 2, 44, 54, 8, 1, 0, 2, 44, 62, + 1, 1, 0, 2, 48, 62, 3, 1, 0, 2, 48, 62, + 4, 1, 0, 2, 48, 76, 5, 1, 0, 2, 48, 62, + 6, 1, 0, 2, 48, 64, 7, 1, 0, 2, 48, 54, + 8, 1, 0, 2, 48, 62, 1, 1, 0, 2, 52, 62, + 3, 1, 0, 2, 52, 64, 4, 1, 0, 2, 52, 76, + 5, 1, 0, 2, 52, 62, 6, 1, 0, 2, 52, 76, + 7, 1, 0, 2, 52, 54, 8, 1, 0, 2, 52, 76, + 1, 1, 0, 2, 56, 62, 3, 1, 0, 2, 56, 64, + 4, 1, 0, 2, 56, 76, 5, 1, 0, 2, 56, 62, + 6, 1, 0, 2, 56, 76, 7, 1, 0, 2, 56, 54, + 8, 1, 0, 2, 56, 76, 1, 1, 0, 2, 60, 62, + 3, 1, 0, 2, 60, 64, 4, 1, 0, 2, 60, 76, + 5, 1, 0, 2, 60, 62, 6, 1, 0, 2, 60, 76, + 7, 1, 0, 2, 60, 54, 8, 1, 0, 2, 60, 76, + 1, 1, 0, 2, 64, 60, 3, 1, 0, 2, 64, 64, + 4, 1, 0, 2, 64, 74, 5, 1, 0, 2, 64, 62, + 6, 1, 0, 2, 64, 74, 7, 1, 0, 2, 64, 54, + 8, 1, 0, 2, 64, 74, 1, 1, 0, 2, 100, 76, + 3, 1, 0, 2, 100, 70, 4, 1, 0, 2, 100, 76, + 5, 1, 0, 2, 100, 62, 6, 1, 0, 2, 100, 70, + 7, 1, 0, 2, 100, 54, 8, 1, 0, 2, 100, 70, + 1, 1, 0, 2, 104, 76, 3, 1, 0, 2, 104, 76, + 4, 1, 0, 2, 104, 76, 5, 1, 0, 2, 104, 62, + 6, 1, 0, 2, 104, 76, 7, 1, 0, 2, 104, 54, + 8, 1, 0, 2, 104, 76, 1, 1, 0, 2, 108, 76, + 3, 1, 0, 2, 108, 76, 4, 1, 0, 2, 108, 76, + 5, 1, 0, 2, 108, 62, 6, 1, 0, 2, 108, 76, + 7, 1, 0, 2, 108, 54, 8, 1, 0, 2, 108, 76, + 1, 1, 0, 2, 112, 76, 3, 1, 0, 2, 112, 76, + 4, 1, 0, 2, 112, 76, 5, 1, 0, 2, 112, 62, + 6, 1, 0, 2, 112, 76, 7, 1, 0, 2, 112, 54, + 8, 1, 0, 2, 112, 76, 1, 1, 0, 2, 116, 76, + 3, 1, 0, 2, 116, 76, 4, 1, 0, 2, 116, 76, + 5, 1, 0, 2, 116, 62, 6, 1, 0, 2, 116, 76, + 7, 1, 0, 2, 116, 54, 8, 1, 0, 2, 116, 76, + 1, 1, 0, 2, 120, 76, 3, 1, 0, 2, 120, 127, + 4, 1, 0, 2, 120, 76, 5, 1, 0, 2, 120, 127, + 6, 1, 0, 2, 120, 76, 7, 1, 0, 2, 120, 54, + 8, 1, 0, 2, 120, 76, 1, 1, 0, 2, 124, 76, + 3, 1, 0, 2, 124, 127, 4, 1, 0, 2, 124, 76, + 5, 1, 0, 2, 124, 127, 6, 1, 0, 2, 124, 76, + 7, 1, 0, 2, 124, 54, 8, 1, 0, 2, 124, 76, + 1, 1, 0, 2, 128, 76, 3, 1, 0, 2, 128, 127, + 4, 1, 0, 2, 128, 76, 5, 1, 0, 2, 128, 127, + 6, 1, 0, 2, 128, 76, 7, 1, 0, 2, 128, 54, + 8, 1, 0, 2, 128, 76, 1, 1, 0, 2, 132, 76, + 3, 1, 0, 2, 132, 76, 4, 1, 0, 2, 132, 76, + 5, 1, 0, 2, 132, 62, 6, 1, 0, 2, 132, 76, + 7, 1, 0, 2, 132, 54, 8, 1, 0, 2, 132, 76, + 1, 1, 0, 2, 136, 76, 3, 1, 0, 2, 136, 76, + 4, 1, 0, 2, 136, 76, 5, 1, 0, 2, 136, 62, + 6, 1, 0, 2, 136, 76, 7, 1, 0, 2, 136, 127, + 8, 1, 0, 2, 136, 76, 1, 1, 0, 2, 140, 76, + 3, 1, 0, 2, 140, 70, 4, 1, 0, 2, 140, 76, + 5, 1, 0, 2, 140, 62, 6, 1, 0, 2, 140, 70, + 7, 1, 0, 2, 140, 127, 8, 1, 0, 2, 140, 70, + 1, 1, 0, 2, 144, 127, 3, 1, 0, 2, 144, 76, + 4, 1, 0, 2, 144, 76, 5, 1, 0, 2, 144, 127, + 6, 1, 0, 2, 144, 76, 7, 1, 0, 2, 144, 127, + 8, 1, 0, 2, 144, 76, 1, 1, 0, 2, 149, 127, + 3, 1, 0, 2, 149, 76, 4, 1, 0, 2, 149, 74, + 5, 1, 0, 2, 149, 76, 6, 1, 0, 2, 149, 76, + 7, 1, 0, 2, 149, 54, 8, 1, 0, 2, 149, 76, + 1, 1, 0, 2, 153, 127, 3, 1, 0, 2, 153, 76, + 4, 1, 0, 2, 153, 74, 5, 1, 0, 2, 153, 76, + 6, 1, 0, 2, 153, 76, 7, 1, 0, 2, 153, 54, + 8, 1, 0, 2, 153, 76, 1, 1, 0, 2, 157, 127, + 3, 1, 0, 2, 157, 76, 4, 1, 0, 2, 157, 74, + 5, 1, 0, 2, 157, 76, 6, 1, 0, 2, 157, 76, + 7, 1, 0, 2, 157, 54, 8, 1, 0, 2, 157, 76, + 1, 1, 0, 2, 161, 127, 3, 1, 0, 2, 161, 76, + 4, 1, 0, 2, 161, 74, 5, 1, 0, 2, 161, 76, + 6, 1, 0, 2, 161, 76, 7, 1, 0, 2, 161, 54, + 8, 1, 0, 2, 161, 76, 1, 1, 0, 2, 165, 127, + 3, 1, 0, 2, 165, 76, 4, 1, 0, 2, 165, 74, + 5, 1, 0, 2, 165, 76, 6, 1, 0, 2, 165, 76, + 7, 1, 0, 2, 165, 54, 8, 1, 0, 2, 165, 76, + 1, 1, 0, 3, 36, 50, 3, 1, 0, 3, 36, 38, + 4, 1, 0, 3, 36, 66, 5, 1, 0, 3, 36, 38, + 6, 1, 0, 3, 36, 52, 7, 1, 0, 3, 36, 30, + 8, 1, 0, 3, 36, 50, 1, 1, 0, 3, 40, 50, + 3, 1, 0, 3, 40, 38, 4, 1, 0, 3, 40, 66, + 5, 1, 0, 3, 40, 38, 6, 1, 0, 3, 40, 52, + 7, 1, 0, 3, 40, 30, 8, 1, 0, 3, 40, 50, + 1, 1, 0, 3, 44, 50, 3, 1, 0, 3, 44, 38, + 4, 1, 0, 3, 44, 66, 5, 1, 0, 3, 44, 38, + 6, 1, 0, 3, 44, 52, 7, 1, 0, 3, 44, 30, + 8, 1, 0, 3, 44, 50, 1, 1, 0, 3, 48, 50, + 3, 1, 0, 3, 48, 38, 4, 1, 0, 3, 48, 66, + 5, 1, 0, 3, 48, 38, 6, 1, 0, 3, 48, 52, + 7, 1, 0, 3, 48, 30, 8, 1, 0, 3, 48, 50, + 1, 1, 0, 3, 52, 50, 3, 1, 0, 3, 52, 40, + 4, 1, 0, 3, 52, 66, 5, 1, 0, 3, 52, 38, + 6, 1, 0, 3, 52, 68, 7, 1, 0, 3, 52, 30, + 8, 1, 0, 3, 52, 68, 1, 1, 0, 3, 56, 50, + 3, 1, 0, 3, 56, 40, 4, 1, 0, 3, 56, 66, + 5, 1, 0, 3, 56, 38, 6, 1, 0, 3, 56, 68, + 7, 1, 0, 3, 56, 30, 8, 1, 0, 3, 56, 68, + 1, 1, 0, 3, 60, 50, 3, 1, 0, 3, 60, 40, + 4, 1, 0, 3, 60, 66, 5, 1, 0, 3, 60, 38, + 6, 1, 0, 3, 60, 66, 7, 1, 0, 3, 60, 30, + 8, 1, 0, 3, 60, 66, 1, 1, 0, 3, 64, 50, + 3, 1, 0, 3, 64, 40, 4, 1, 0, 3, 64, 66, + 5, 1, 0, 3, 64, 38, 6, 1, 0, 3, 64, 68, + 7, 1, 0, 3, 64, 30, 8, 1, 0, 3, 64, 68, + 1, 1, 0, 3, 100, 70, 3, 1, 0, 3, 100, 60, + 4, 1, 0, 3, 100, 64, 5, 1, 0, 3, 100, 38, + 6, 1, 0, 3, 100, 60, 7, 1, 0, 3, 100, 30, + 8, 1, 0, 3, 100, 60, 1, 1, 0, 3, 104, 70, + 3, 1, 0, 3, 104, 68, 4, 1, 0, 3, 104, 64, + 5, 1, 0, 3, 104, 38, 6, 1, 0, 3, 104, 68, + 7, 1, 0, 3, 104, 30, 8, 1, 0, 3, 104, 68, + 1, 1, 0, 3, 108, 70, 3, 1, 0, 3, 108, 68, + 4, 1, 0, 3, 108, 64, 5, 1, 0, 3, 108, 38, + 6, 1, 0, 3, 108, 68, 7, 1, 0, 3, 108, 30, + 8, 1, 0, 3, 108, 68, 1, 1, 0, 3, 112, 70, + 3, 1, 0, 3, 112, 68, 4, 1, 0, 3, 112, 64, + 5, 1, 0, 3, 112, 38, 6, 1, 0, 3, 112, 68, + 7, 1, 0, 3, 112, 30, 8, 1, 0, 3, 112, 68, + 1, 1, 0, 3, 116, 70, 3, 1, 0, 3, 116, 68, + 4, 1, 0, 3, 116, 64, 5, 1, 0, 3, 116, 38, + 6, 1, 0, 3, 116, 68, 7, 1, 0, 3, 116, 30, + 8, 1, 0, 3, 116, 68, 1, 1, 0, 3, 120, 70, + 3, 1, 0, 3, 120, 127, 4, 1, 0, 3, 120, 64, + 5, 1, 0, 3, 120, 127, 6, 1, 0, 3, 120, 68, + 7, 1, 0, 3, 120, 30, 8, 1, 0, 3, 120, 68, + 1, 1, 0, 3, 124, 70, 3, 1, 0, 3, 124, 127, + 4, 1, 0, 3, 124, 64, 5, 1, 0, 3, 124, 127, + 6, 1, 0, 3, 124, 68, 7, 1, 0, 3, 124, 30, + 8, 1, 0, 3, 124, 68, 1, 1, 0, 3, 128, 70, + 3, 1, 0, 3, 128, 127, 4, 1, 0, 3, 128, 64, + 5, 1, 0, 3, 128, 127, 6, 1, 0, 3, 128, 68, + 7, 1, 0, 3, 128, 30, 8, 1, 0, 3, 128, 68, + 1, 1, 0, 3, 132, 70, 3, 1, 0, 3, 132, 68, + 4, 1, 0, 3, 132, 64, 5, 1, 0, 3, 132, 38, + 6, 1, 0, 3, 132, 68, 7, 1, 0, 3, 132, 30, + 8, 1, 0, 3, 132, 68, 1, 1, 0, 3, 136, 70, + 3, 1, 0, 3, 136, 68, 4, 1, 0, 3, 136, 64, + 5, 1, 0, 3, 136, 38, 6, 1, 0, 3, 136, 68, + 7, 1, 0, 3, 136, 127, 8, 1, 0, 3, 136, 68, + 1, 1, 0, 3, 140, 70, 3, 1, 0, 3, 140, 60, + 4, 1, 0, 3, 140, 64, 5, 1, 0, 3, 140, 38, + 6, 1, 0, 3, 140, 60, 7, 1, 0, 3, 140, 127, + 8, 1, 0, 3, 140, 60, 1, 1, 0, 3, 144, 127, + 3, 1, 0, 3, 144, 68, 4, 1, 0, 3, 144, 64, + 5, 1, 0, 3, 144, 127, 6, 1, 0, 3, 144, 68, + 7, 1, 0, 3, 144, 127, 8, 1, 0, 3, 144, 68, + 1, 1, 0, 3, 149, 127, 3, 1, 0, 3, 149, 76, + 4, 1, 0, 3, 149, 60, 5, 1, 0, 3, 149, 76, + 6, 1, 0, 3, 149, 76, 7, 1, 0, 3, 149, 30, + 8, 1, 0, 3, 149, 72, 1, 1, 0, 3, 153, 127, + 3, 1, 0, 3, 153, 76, 4, 1, 0, 3, 153, 60, + 5, 1, 0, 3, 153, 76, 6, 1, 0, 3, 153, 76, + 7, 1, 0, 3, 153, 30, 8, 1, 0, 3, 153, 76, + 1, 1, 0, 3, 157, 127, 3, 1, 0, 3, 157, 76, + 4, 1, 0, 3, 157, 60, 5, 1, 0, 3, 157, 76, + 6, 1, 0, 3, 157, 76, 7, 1, 0, 3, 157, 30, + 8, 1, 0, 3, 157, 76, 1, 1, 0, 3, 161, 127, + 3, 1, 0, 3, 161, 76, 4, 1, 0, 3, 161, 60, + 5, 1, 0, 3, 161, 76, 6, 1, 0, 3, 161, 76, + 7, 1, 0, 3, 161, 30, 8, 1, 0, 3, 161, 76, + 1, 1, 0, 3, 165, 127, 3, 1, 0, 3, 165, 76, + 4, 1, 0, 3, 165, 60, 5, 1, 0, 3, 165, 76, + 6, 1, 0, 3, 165, 76, 7, 1, 0, 3, 165, 30, + 8, 1, 0, 3, 165, 76, 1, 1, 1, 2, 38, 62, + 3, 1, 1, 2, 38, 64, 4, 1, 1, 2, 38, 72, + 5, 1, 1, 2, 38, 64, 6, 1, 1, 2, 38, 64, + 7, 1, 1, 2, 38, 54, 8, 1, 1, 2, 38, 62, + 1, 1, 1, 2, 46, 62, 3, 1, 1, 2, 46, 64, + 4, 1, 1, 2, 46, 72, 5, 1, 1, 2, 46, 64, + 6, 1, 1, 2, 46, 64, 7, 1, 1, 2, 46, 54, + 8, 1, 1, 2, 46, 62, 1, 1, 1, 2, 54, 62, + 3, 1, 1, 2, 54, 64, 4, 1, 1, 2, 54, 72, + 5, 1, 1, 2, 54, 64, 6, 1, 1, 2, 54, 72, + 7, 1, 1, 2, 54, 54, 8, 1, 1, 2, 54, 72, + 1, 1, 1, 2, 62, 62, 3, 1, 1, 2, 62, 64, + 4, 1, 1, 2, 62, 70, 5, 1, 1, 2, 62, 64, + 6, 1, 1, 2, 62, 64, 7, 1, 1, 2, 62, 54, + 8, 1, 1, 2, 62, 64, 1, 1, 1, 2, 102, 72, + 3, 1, 1, 2, 102, 58, 4, 1, 1, 2, 102, 72, + 5, 1, 1, 2, 102, 64, 6, 1, 1, 2, 102, 58, + 7, 1, 1, 2, 102, 54, 8, 1, 1, 2, 102, 58, + 1, 1, 1, 2, 110, 72, 3, 1, 1, 2, 110, 72, + 4, 1, 1, 2, 110, 72, 5, 1, 1, 2, 110, 64, + 6, 1, 1, 2, 110, 72, 7, 1, 1, 2, 110, 54, + 8, 1, 1, 2, 110, 72, 1, 1, 1, 2, 118, 72, + 3, 1, 1, 2, 118, 127, 4, 1, 1, 2, 118, 72, + 5, 1, 1, 2, 118, 127, 6, 1, 1, 2, 118, 72, + 7, 1, 1, 2, 118, 54, 8, 1, 1, 2, 118, 72, + 1, 1, 1, 2, 126, 72, 3, 1, 1, 2, 126, 127, + 4, 1, 1, 2, 126, 72, 5, 1, 1, 2, 126, 127, + 6, 1, 1, 2, 126, 72, 7, 1, 1, 2, 126, 54, + 8, 1, 1, 2, 126, 72, 1, 1, 1, 2, 134, 72, + 3, 1, 1, 2, 134, 72, 4, 1, 1, 2, 134, 72, + 5, 1, 1, 2, 134, 64, 6, 1, 1, 2, 134, 72, + 7, 1, 1, 2, 134, 127, 8, 1, 1, 2, 134, 72, + 1, 1, 1, 2, 142, 127, 3, 1, 1, 2, 142, 72, + 4, 1, 1, 2, 142, 72, 5, 1, 1, 2, 142, 127, + 6, 1, 1, 2, 142, 72, 7, 1, 1, 2, 142, 127, + 8, 1, 1, 2, 142, 72, 1, 1, 1, 2, 151, 127, + 3, 1, 1, 2, 151, 72, 4, 1, 1, 2, 151, 72, + 5, 1, 1, 2, 151, 72, 6, 1, 1, 2, 151, 72, + 7, 1, 1, 2, 151, 54, 8, 1, 1, 2, 151, 72, + 1, 1, 1, 2, 159, 127, 3, 1, 1, 2, 159, 72, + 4, 1, 1, 2, 159, 72, 5, 1, 1, 2, 159, 72, + 6, 1, 1, 2, 159, 72, 7, 1, 1, 2, 159, 54, + 8, 1, 1, 2, 159, 72, 1, 1, 1, 3, 38, 50, + 3, 1, 1, 3, 38, 40, 4, 1, 1, 3, 38, 62, + 5, 1, 1, 3, 38, 40, 6, 1, 1, 3, 38, 52, + 7, 1, 1, 3, 38, 30, 8, 1, 1, 3, 38, 50, + 1, 1, 1, 3, 46, 50, 3, 1, 1, 3, 46, 40, + 4, 1, 1, 3, 46, 62, 5, 1, 1, 3, 46, 40, + 6, 1, 1, 3, 46, 52, 7, 1, 1, 3, 46, 30, + 8, 1, 1, 3, 46, 50, 1, 1, 1, 3, 54, 50, + 3, 1, 1, 3, 54, 40, 4, 1, 1, 3, 54, 62, + 5, 1, 1, 3, 54, 40, 6, 1, 1, 3, 54, 68, + 7, 1, 1, 3, 54, 30, 8, 1, 1, 3, 54, 68, + 1, 1, 1, 3, 62, 48, 3, 1, 1, 3, 62, 40, + 4, 1, 1, 3, 62, 58, 5, 1, 1, 3, 62, 40, + 6, 1, 1, 3, 62, 58, 7, 1, 1, 3, 62, 30, + 8, 1, 1, 3, 62, 58, 1, 1, 1, 3, 102, 70, + 3, 1, 1, 3, 102, 54, 4, 1, 1, 3, 102, 64, + 5, 1, 1, 3, 102, 40, 6, 1, 1, 3, 102, 54, + 7, 1, 1, 3, 102, 30, 8, 1, 1, 3, 102, 54, + 1, 1, 1, 3, 110, 70, 3, 1, 1, 3, 110, 68, + 4, 1, 1, 3, 110, 64, 5, 1, 1, 3, 110, 40, + 6, 1, 1, 3, 110, 68, 7, 1, 1, 3, 110, 30, + 8, 1, 1, 3, 110, 68, 1, 1, 1, 3, 118, 70, + 3, 1, 1, 3, 118, 127, 4, 1, 1, 3, 118, 64, + 5, 1, 1, 3, 118, 127, 6, 1, 1, 3, 118, 68, + 7, 1, 1, 3, 118, 30, 8, 1, 1, 3, 118, 68, + 1, 1, 1, 3, 126, 70, 3, 1, 1, 3, 126, 127, + 4, 1, 1, 3, 126, 64, 5, 1, 1, 3, 126, 127, + 6, 1, 1, 3, 126, 68, 7, 1, 1, 3, 126, 30, + 8, 1, 1, 3, 126, 68, 1, 1, 1, 3, 134, 70, + 3, 1, 1, 3, 134, 68, 4, 1, 1, 3, 134, 64, + 5, 1, 1, 3, 134, 40, 6, 1, 1, 3, 134, 68, + 7, 1, 1, 3, 134, 127, 8, 1, 1, 3, 134, 68, + 1, 1, 1, 3, 142, 127, 3, 1, 1, 3, 142, 68, + 4, 1, 1, 3, 142, 64, 5, 1, 1, 3, 142, 127, + 6, 1, 1, 3, 142, 68, 7, 1, 1, 3, 142, 127, + 8, 1, 1, 3, 142, 68, 1, 1, 1, 3, 151, 127, + 3, 1, 1, 3, 151, 72, 4, 1, 1, 3, 151, 66, + 5, 1, 1, 3, 151, 72, 6, 1, 1, 3, 151, 72, + 7, 1, 1, 3, 151, 30, 8, 1, 1, 3, 151, 68, + 1, 1, 1, 3, 159, 127, 3, 1, 1, 3, 159, 72, + 4, 1, 1, 3, 159, 66, 5, 1, 1, 3, 159, 72, + 6, 1, 1, 3, 159, 72, 7, 1, 1, 3, 159, 30, + 8, 1, 1, 3, 159, 72, 1, 1, 2, 4, 42, 64, + 3, 1, 2, 4, 42, 64, 4, 1, 2, 4, 42, 68, + 5, 1, 2, 4, 42, 64, 6, 1, 2, 4, 42, 64, + 7, 1, 2, 4, 42, 54, 8, 1, 2, 4, 42, 62, + 1, 1, 2, 4, 58, 64, 3, 1, 2, 4, 58, 62, + 4, 1, 2, 4, 58, 64, 5, 1, 2, 4, 58, 64, + 6, 1, 2, 4, 58, 62, 7, 1, 2, 4, 58, 54, + 8, 1, 2, 4, 58, 62, 1, 1, 2, 4, 106, 72, + 3, 1, 2, 4, 106, 58, 4, 1, 2, 4, 106, 66, + 5, 1, 2, 4, 106, 64, 6, 1, 2, 4, 106, 58, + 7, 1, 2, 4, 106, 54, 8, 1, 2, 4, 106, 58, + 1, 1, 2, 4, 122, 72, 3, 1, 2, 4, 122, 127, + 4, 1, 2, 4, 122, 68, 5, 1, 2, 4, 122, 127, + 6, 1, 2, 4, 122, 72, 7, 1, 2, 4, 122, 54, + 8, 1, 2, 4, 122, 72, 1, 1, 2, 4, 138, 127, + 3, 1, 2, 4, 138, 72, 4, 1, 2, 4, 138, 68, + 5, 1, 2, 4, 138, 127, 6, 1, 2, 4, 138, 72, + 7, 1, 2, 4, 138, 127, 8, 1, 2, 4, 138, 72, + 1, 1, 2, 4, 155, 127, 3, 1, 2, 4, 155, 72, + 4, 1, 2, 4, 155, 68, 5, 1, 2, 4, 155, 72, + 6, 1, 2, 4, 155, 72, 7, 1, 2, 4, 155, 54, + 8, 1, 2, 4, 155, 68, 1, 1, 2, 5, 42, 50, + 3, 1, 2, 5, 42, 40, 4, 1, 2, 5, 42, 58, + 5, 1, 2, 5, 42, 40, 6, 1, 2, 5, 42, 52, + 7, 1, 2, 5, 42, 30, 8, 1, 2, 5, 42, 50, + 1, 1, 2, 5, 58, 50, 3, 1, 2, 5, 58, 40, + 4, 1, 2, 5, 58, 56, 5, 1, 2, 5, 58, 40, + 6, 1, 2, 5, 58, 52, 7, 1, 2, 5, 58, 30, + 8, 1, 2, 5, 58, 52, 1, 1, 2, 5, 106, 72, + 3, 1, 2, 5, 106, 50, 4, 1, 2, 5, 106, 56, + 5, 1, 2, 5, 106, 40, 6, 1, 2, 5, 106, 50, + 7, 1, 2, 5, 106, 30, 8, 1, 2, 5, 106, 50, + 1, 1, 2, 5, 122, 72, 3, 1, 2, 5, 122, 127, + 4, 1, 2, 5, 122, 56, 5, 1, 2, 5, 122, 127, + 6, 1, 2, 5, 122, 66, 7, 1, 2, 5, 122, 30, + 8, 1, 2, 5, 122, 66, 1, 1, 2, 5, 138, 127, + 3, 1, 2, 5, 138, 66, 4, 1, 2, 5, 138, 58, + 5, 1, 2, 5, 138, 127, 6, 1, 2, 5, 138, 66, + 7, 1, 2, 5, 138, 127, 8, 1, 2, 5, 138, 66, + 1, 1, 2, 5, 155, 127, 3, 1, 2, 5, 155, 62, + 4, 1, 2, 5, 155, 58, 5, 1, 2, 5, 155, 72, + 6, 1, 2, 5, 155, 62, 7, 1, 2, 5, 155, 30, + 8, 1, 2, 5, 155, 62 }; RTW_DECL_TABLE_TXPWR_LMT(rtw8822c_txpwr_lmt_type0); diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c index e32faf8bead9..8eaa9809ca44 100644 --- a/drivers/net/wireless/realtek/rtw88/tx.c +++ b/drivers/net/wireless/realtek/rtw88/tx.c @@ -362,6 +362,6 @@ void rtw_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, pkt_info->bmc = bmc; pkt_info->tx_pkt_size = skb->len; pkt_info->offset = chip->tx_pkt_desc_sz; - pkt_info->qsel = skb->priority; + pkt_info->qsel = TX_DESC_QSEL_MGMT; pkt_info->ls = true; } |