Hi Kalle, This patch added a comment about our watch dog timer, please let me know if you are OK with it. Also if you have other questions about the series, just point it out and I will try to fix it. Thanks. Yan-Hsuan > -----Original Message----- > From: linux-wireless-owner@xxxxxxxxxxxxxxx > [mailto:linux-wireless-owner@xxxxxxxxxxxxxxx] On Behalf Of > yhchuang@xxxxxxxxxxx > Sent: Friday, November 16, 2018 7:31 PM > To: kvalo@xxxxxxxxxxxxxx > Cc: Larry.Finger@xxxxxxxxxxxx; linux-wireless@xxxxxxxxxxxxxxx; Pkshih; Andy > Huang > Subject: [PATCH v2 01/13] rtw88: main files > > From: Yan-Hsuan Chuang <yhchuang@xxxxxxxxxxx> > > main files for Realtek 802.11ac wireless network chips > > Signed-off-by: Yan-Hsuan Chuang <yhchuang@xxxxxxxxxxx> > --- > drivers/net/wireless/realtek/rtw88/mac80211.c | 480 ++++++++++ > drivers/net/wireless/realtek/rtw88/main.c | 1190 > +++++++++++++++++++++++++ > drivers/net/wireless/realtek/rtw88/main.h | 1119 > +++++++++++++++++++++++ > drivers/net/wireless/realtek/rtw88/reg.h | 411 +++++++++ > 4 files changed, 3200 insertions(+) > create mode 100644 drivers/net/wireless/realtek/rtw88/mac80211.c > create mode 100644 drivers/net/wireless/realtek/rtw88/main.c > create mode 100644 drivers/net/wireless/realtek/rtw88/main.h > create mode 100644 drivers/net/wireless/realtek/rtw88/reg.h > > diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c > b/drivers/net/wireless/realtek/rtw88/mac80211.c > new file mode 100644 > index 0000000..17b3651 > --- /dev/null > +++ b/drivers/net/wireless/realtek/rtw88/mac80211.c > @@ -0,0 +1,480 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright(c) 2018 Realtek Corporation. > + */ > + > +#include "main.h" > +#include "sec.h" > +#include "tx.h" > +#include "fw.h" > +#include "mac.h" > +#include "ps.h" > +#include "reg.h" > +#include "debug.h" > + > +static void rtw_ops_tx(struct ieee80211_hw *hw, > + struct ieee80211_tx_control *control, > + struct sk_buff *skb) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct rtw_tx_pkt_info pkt_info = {0}; > + > + if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING)) > + goto out; > + > + rtw_tx_pkt_info_update(rtwdev, &pkt_info, control, skb); > + if (rtw_hci_tx(rtwdev, &pkt_info, skb)) > + goto out; > + > + return; > + > +out: > + ieee80211_free_txskb(hw, skb); > +} > + > +static int rtw_ops_start(struct ieee80211_hw *hw) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + int ret; > + > + mutex_lock(&rtwdev->mutex); > + ret = rtw_core_start(rtwdev); > + mutex_unlock(&rtwdev->mutex); > + > + return ret; > +} > + > +static void rtw_ops_stop(struct ieee80211_hw *hw) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + > + mutex_lock(&rtwdev->mutex); > + rtw_core_stop(rtwdev); > + mutex_unlock(&rtwdev->mutex); > +} > + > +static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + int ret = 0; > + > + mutex_lock(&rtwdev->mutex); > + > + if (changed & IEEE80211_CONF_CHANGE_IDLE) { > + if (hw->conf.flags & IEEE80211_CONF_IDLE) { > + rtw_enter_ips(rtwdev); > + } else { > + ret = rtw_leave_ips(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to leave idle state\n"); > + goto out; > + } > + } > + } > + > + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) > + rtw_set_channel(rtwdev); > + > +out: > + mutex_unlock(&rtwdev->mutex); > + return ret; > +} > + > +static const struct rtw_vif_port rtw_vif_port[] = { > + [0] = { > + .mac_addr = {.addr = 0x0610}, > + .bssid = {.addr = 0x0618}, > + .net_type = {.addr = 0x0100, .mask = 0x30000}, > + .aid = {.addr = 0x06a8, .mask = 0x7ff}, > + }, > + [1] = { > + .mac_addr = {.addr = 0x0700}, > + .bssid = {.addr = 0x0708}, > + .net_type = {.addr = 0x0100, .mask = 0xc0000}, > + .aid = {.addr = 0x0710, .mask = 0x7ff}, > + }, > + [2] = { > + .mac_addr = {.addr = 0x1620}, > + .bssid = {.addr = 0x1628}, > + .net_type = {.addr = 0x1100, .mask = 0x3}, > + .aid = {.addr = 0x1600, .mask = 0x7ff}, > + }, > + [3] = { > + .mac_addr = {.addr = 0x1630}, > + .bssid = {.addr = 0x1638}, > + .net_type = {.addr = 0x1100, .mask = 0xc}, > + .aid = {.addr = 0x1604, .mask = 0x7ff}, > + }, > + [4] = { > + .mac_addr = {.addr = 0x1640}, > + .bssid = {.addr = 0x1648}, > + .net_type = {.addr = 0x1100, .mask = 0x30}, > + .aid = {.addr = 0x1608, .mask = 0x7ff}, > + }, > +}; > + > +static int rtw_ops_add_interface(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; > + enum rtw_net_type net_type; > + u32 config = 0; > + u8 port = 0; > + > + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; > + rtwvif->port = port; > + rtwvif->vif = vif; > + rtwvif->stats.tx_unicast = 0; > + rtwvif->stats.rx_unicast = 0; > + rtwvif->stats.tx_cnt = 0; > + rtwvif->stats.rx_cnt = 0; > + rtwvif->in_lps = false; > + rtwvif->conf = &rtw_vif_port[port]; > + > + mutex_lock(&rtwdev->mutex); > + > + switch (vif->type) { > + case NL80211_IFTYPE_AP: > + case NL80211_IFTYPE_MESH_POINT: > + net_type = RTW_NET_AP_MODE; > + break; > + case NL80211_IFTYPE_ADHOC: > + net_type = RTW_NET_AD_HOC; > + break; > + case NL80211_IFTYPE_STATION: > + default: > + net_type = RTW_NET_NO_LINK; > + break; > + } > + > + ether_addr_copy(rtwvif->mac_addr, vif->addr); > + config |= PORT_SET_MAC_ADDR; > + rtwvif->net_type = net_type; > + config |= PORT_SET_NET_TYPE; > + rtw_vif_port_config(rtwdev, rtwvif, config); > + > + mutex_unlock(&rtwdev->mutex); > + > + rtw_info(rtwdev, "start vif %pM on port %d\n", vif->addr, rtwvif->port); > + return 0; > +} > + > +static void rtw_ops_remove_interface(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; > + > + rtw_info(rtwdev, "stop vif %pM on port %d\n", vif->addr, rtwvif->port); > + > + mutex_lock(&rtwdev->mutex); > + > + eth_zero_addr(rtwvif->mac_addr); > + config |= PORT_SET_MAC_ADDR; > + rtwvif->net_type = RTW_NET_NO_LINK; > + config |= PORT_SET_NET_TYPE; > + rtw_vif_port_config(rtwdev, rtwvif, config); > + > + mutex_unlock(&rtwdev->mutex); > +} > + > +static void rtw_ops_configure_filter(struct ieee80211_hw *hw, > + unsigned int changed_flags, > + unsigned int *new_flags, > + u64 multicast) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + > + *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL | > + FIF_BCN_PRBRESP_PROMISC; > + > + mutex_lock(&rtwdev->mutex); > + > + if (changed_flags & FIF_ALLMULTI) { > + if (*new_flags & FIF_ALLMULTI) > + rtwdev->hal.rcr |= BIT_AM | BIT_AB; > + else > + rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB); > + } > + if (changed_flags & FIF_FCSFAIL) { > + if (*new_flags & FIF_FCSFAIL) > + rtwdev->hal.rcr |= BIT_ACRC32; > + else > + rtwdev->hal.rcr &= ~(BIT_ACRC32); > + } > + if (changed_flags & FIF_OTHER_BSS) { > + if (*new_flags & FIF_OTHER_BSS) > + rtwdev->hal.rcr |= BIT_AAP; > + else > + rtwdev->hal.rcr &= ~(BIT_AAP); > + } > + if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { > + if (*new_flags & FIF_BCN_PRBRESP_PROMISC) > + rtwdev->hal.rcr &= ~(BIT_CBSSID_BCN | BIT_CBSSID_DATA); > + else > + rtwdev->hal.rcr |= BIT_CBSSID_BCN; > + } > + > + rtw_dbg(rtwdev, "config rx filter, changed=0x%08x, new=0x%08x, > rcr=0x%08x\n", > + changed_flags, *new_flags, rtwdev->hal.rcr); > + > + rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr); > + > + mutex_unlock(&rtwdev->mutex); > +} > + > +static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif, > + struct ieee80211_bss_conf *conf, > + u32 changed) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; > + u32 config = 0; > + > + mutex_lock(&rtwdev->mutex); > + > + if (changed & BSS_CHANGED_ASSOC) { > + struct rtw_chip_info *chip = rtwdev->chip; > + enum rtw_net_type net_type; > + > + if (conf->assoc) { > + net_type = RTW_NET_MGD_LINKED; > + chip->ops->do_iqk(rtwdev); > + > + rtwvif->aid = conf->aid; > + rtw_add_rsvd_page(rtwdev, RSVD_PS_POLL, true); > + rtw_add_rsvd_page(rtwdev, RSVD_QOS_NULL, true); > + rtw_add_rsvd_page(rtwdev, RSVD_NULL, true); > + rtw_fw_download_rsvd_page(rtwdev, vif); > + } else { > + net_type = RTW_NET_NO_LINK; > + rtwvif->aid = 0; > + rtw_reset_rsvd_page(rtwdev); > + } > + > + rtwvif->net_type = net_type; > + config |= PORT_SET_NET_TYPE; > + config |= PORT_SET_AID; > + } > + > + if (changed & BSS_CHANGED_BSSID) { > + ether_addr_copy(rtwvif->bssid, conf->bssid); > + config |= PORT_SET_BSSID; > + } > + > + if (changed & BSS_CHANGED_BEACON) > + rtw_fw_download_rsvd_page(rtwdev, vif); > + > + rtw_vif_port_config(rtwdev, rtwvif, config); > + > + mutex_unlock(&rtwdev->mutex); > +} > + > +static u8 rtw_acquire_macid(struct rtw_dev *rtwdev) > +{ > + unsigned long mac_id; > + > + mac_id = find_first_zero_bit(rtwdev->mac_id_map, > RTW_MAX_MAC_ID_NUM); > + if (mac_id < RTW_MAX_MAC_ID_NUM) > + set_bit(mac_id, rtwdev->mac_id_map); > + > + return mac_id; > +} > + > +static void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id) > +{ > + clear_bit(mac_id, rtwdev->mac_id_map); > +} > + > +static int rtw_ops_sta_add(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif, > + struct ieee80211_sta *sta) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; > + int ret = 0; > + > + mutex_lock(&rtwdev->mutex); > + > + si->mac_id = rtw_acquire_macid(rtwdev); > + if (si->mac_id >= RTW_MAX_MAC_ID_NUM) { > + ret = -ENOSPC; > + goto out; > + } > + > + si->sta = sta; > + si->vif = vif; > + si->init_ra_lv = 1; > + ewma_rssi_init(&si->avg_rssi); > + > + rtw_update_sta_info(rtwdev, si); > + rtw_fw_media_status_report(rtwdev, si->mac_id, true); > + > + rtwdev->sta_cnt++; > + > + rtw_info(rtwdev, "sta %pM joined with macid %d\n", > + sta->addr, si->mac_id); > + > +out: > + mutex_unlock(&rtwdev->mutex); > + return ret; > +} > + > +static int rtw_ops_sta_remove(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif, > + struct ieee80211_sta *sta) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; > + > + mutex_lock(&rtwdev->mutex); > + > + rtw_release_macid(rtwdev, si->mac_id); > + rtw_fw_media_status_report(rtwdev, si->mac_id, false); > + > + rtwdev->sta_cnt--; > + > + rtw_info(rtwdev, "sta %pM with macid %d left\n", > + sta->addr, si->mac_id); > + > + mutex_unlock(&rtwdev->mutex); > + return 0; > +} > + > +static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd > cmd, > + struct ieee80211_vif *vif, struct ieee80211_sta *sta, > + struct ieee80211_key_conf *key) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct rtw_sec_desc *sec = &rtwdev->sec; > + u8 hw_key_type; > + u8 hw_key_idx; > + int ret = 0; > + > + switch (key->cipher) { > + case WLAN_CIPHER_SUITE_WEP40: > + hw_key_type = RTW_CAM_WEP40; > + break; > + case WLAN_CIPHER_SUITE_WEP104: > + hw_key_type = RTW_CAM_WEP104; > + break; > + case WLAN_CIPHER_SUITE_TKIP: > + hw_key_type = RTW_CAM_TKIP; > + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; > + break; > + case WLAN_CIPHER_SUITE_CCMP: > + hw_key_type = RTW_CAM_AES; > + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; > + break; > + case WLAN_CIPHER_SUITE_AES_CMAC: > + case WLAN_CIPHER_SUITE_BIP_CMAC_256: > + case WLAN_CIPHER_SUITE_BIP_GMAC_128: > + case WLAN_CIPHER_SUITE_BIP_GMAC_256: > + /* suppress error messages */ > + return -EOPNOTSUPP; > + default: > + return -ENOTSUPP; > + } > + > + mutex_lock(&rtwdev->mutex); > + > + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { > + hw_key_idx = rtw_sec_get_free_cam(sec); > + } else { > + /* multiple interfaces? */ > + hw_key_idx = key->keyidx; > + } > + > + if (hw_key_idx > sec->total_cam_num) { > + ret = -ENOSPC; > + goto out; > + } > + > + switch (cmd) { > + case SET_KEY: > + /* need sw generated IV */ > + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; > + key->hw_key_idx = hw_key_idx; > + rtw_sec_write_cam(rtwdev, sec, sta, key, > + hw_key_type, hw_key_idx); > + break; > + case DISABLE_KEY: > + rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx); > + break; > + } > + > +out: > + mutex_unlock(&rtwdev->mutex); > + > + return ret; > +} > + > +static int rtw_ops_ampdu_action(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif, > + struct ieee80211_ampdu_params *params) > +{ > + struct ieee80211_sta *sta = params->sta; > + u16 tid = params->tid; > + > + switch (params->action) { > + case IEEE80211_AMPDU_TX_START: > + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); > + break; > + case IEEE80211_AMPDU_TX_STOP_CONT: > + case IEEE80211_AMPDU_TX_STOP_FLUSH: > + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: > + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); > + break; > + case IEEE80211_AMPDU_TX_OPERATIONAL: > + case IEEE80211_AMPDU_RX_START: > + case IEEE80211_AMPDU_RX_STOP: > + break; > + default: > + WARN_ON(1); > + return -ENOTSUPP; > + } > + > + return 0; > +} > + > +static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif, > + const u8 *mac_addr) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; > + > + rtw_leave_lps(rtwdev, rtwvif); > + > + rtw_flag_set(rtwdev, RTW_FLAG_DIG_DISABLE); > + rtw_flag_set(rtwdev, RTW_FLAG_SCANNING); > +} > + > +static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw, > + struct ieee80211_vif *vif) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + > + rtw_flag_clear(rtwdev, RTW_FLAG_SCANNING); > + rtw_flag_clear(rtwdev, RTW_FLAG_DIG_DISABLE); > +} > + > +const struct ieee80211_ops rtw_ops = { > + .tx = rtw_ops_tx, > + .start = rtw_ops_start, > + .stop = rtw_ops_stop, > + .config = rtw_ops_config, > + .add_interface = rtw_ops_add_interface, > + .remove_interface = rtw_ops_remove_interface, > + .configure_filter = rtw_ops_configure_filter, > + .bss_info_changed = rtw_ops_bss_info_changed, > + .sta_add = rtw_ops_sta_add, > + .sta_remove = rtw_ops_sta_remove, > + .set_key = rtw_ops_set_key, > + .ampdu_action = rtw_ops_ampdu_action, > + .sw_scan_start = rtw_ops_sw_scan_start, > + .sw_scan_complete = rtw_ops_sw_scan_complete, > +}; > +EXPORT_SYMBOL(rtw_ops); > diff --git a/drivers/net/wireless/realtek/rtw88/main.c > b/drivers/net/wireless/realtek/rtw88/main.c > new file mode 100644 > index 0000000..a189c45 > --- /dev/null > +++ b/drivers/net/wireless/realtek/rtw88/main.c > @@ -0,0 +1,1190 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* Copyright(c) 2018 Realtek Corporation. > + */ > + > +#include "main.h" > +#include "regd.h" > +#include "fw.h" > +#include "ps.h" > +#include "sec.h" > +#include "mac.h" > +#include "phy.h" > +#include "reg.h" > +#include "efuse.h" > +#include "debug.h" > + > +static struct ieee80211_channel rtw_channeltable_2g[] = { > + {.center_freq = 2412, .hw_value = 1,}, > + {.center_freq = 2417, .hw_value = 2,}, > + {.center_freq = 2422, .hw_value = 3,}, > + {.center_freq = 2427, .hw_value = 4,}, > + {.center_freq = 2432, .hw_value = 5,}, > + {.center_freq = 2437, .hw_value = 6,}, > + {.center_freq = 2442, .hw_value = 7,}, > + {.center_freq = 2447, .hw_value = 8,}, > + {.center_freq = 2452, .hw_value = 9,}, > + {.center_freq = 2457, .hw_value = 10,}, > + {.center_freq = 2462, .hw_value = 11,}, > + {.center_freq = 2467, .hw_value = 12,}, > + {.center_freq = 2472, .hw_value = 13,}, > + {.center_freq = 2484, .hw_value = 14,}, > +}; > + > +static struct ieee80211_channel rtw_channeltable_5g[] = { > + {.center_freq = 5180, .hw_value = 36,}, > + {.center_freq = 5200, .hw_value = 40,}, > + {.center_freq = 5220, .hw_value = 44,}, > + {.center_freq = 5240, .hw_value = 48,}, > + {.center_freq = 5260, .hw_value = 52,}, > + {.center_freq = 5280, .hw_value = 56,}, > + {.center_freq = 5300, .hw_value = 60,}, > + {.center_freq = 5320, .hw_value = 64,}, > + {.center_freq = 5500, .hw_value = 100,}, > + {.center_freq = 5520, .hw_value = 104,}, > + {.center_freq = 5540, .hw_value = 108,}, > + {.center_freq = 5560, .hw_value = 112,}, > + {.center_freq = 5580, .hw_value = 116,}, > + {.center_freq = 5600, .hw_value = 120,}, > + {.center_freq = 5620, .hw_value = 124,}, > + {.center_freq = 5640, .hw_value = 128,}, > + {.center_freq = 5660, .hw_value = 132,}, > + {.center_freq = 5680, .hw_value = 136,}, > + {.center_freq = 5700, .hw_value = 140,}, > + {.center_freq = 5745, .hw_value = 149,}, > + {.center_freq = 5765, .hw_value = 153,}, > + {.center_freq = 5785, .hw_value = 157,}, > + {.center_freq = 5805, .hw_value = 161,}, > + {.center_freq = 5825, .hw_value = 165, > + .flags = IEEE80211_CHAN_NO_HT40MINUS}, > +}; > + > +static struct ieee80211_rate rtw_ratetable[] = { > + {.bitrate = 10, .hw_value = 0x00,}, > + {.bitrate = 20, .hw_value = 0x01,}, > + {.bitrate = 55, .hw_value = 0x02,}, > + {.bitrate = 110, .hw_value = 0x03,}, > + {.bitrate = 60, .hw_value = 0x04,}, > + {.bitrate = 90, .hw_value = 0x05,}, > + {.bitrate = 120, .hw_value = 0x06,}, > + {.bitrate = 180, .hw_value = 0x07,}, > + {.bitrate = 240, .hw_value = 0x08,}, > + {.bitrate = 360, .hw_value = 0x09,}, > + {.bitrate = 480, .hw_value = 0x0a,}, > + {.bitrate = 540, .hw_value = 0x0b,}, > +}; > + > +static struct ieee80211_supported_band rtw_band_2ghz = { > + .band = NL80211_BAND_2GHZ, > + > + .channels = rtw_channeltable_2g, > + .n_channels = ARRAY_SIZE(rtw_channeltable_2g), > + > + .bitrates = rtw_ratetable, > + .n_bitrates = ARRAY_SIZE(rtw_ratetable), > + > + .ht_cap = {0}, > + .vht_cap = {0}, > +}; > + > +static struct ieee80211_supported_band rtw_band_5ghz = { > + .band = NL80211_BAND_5GHZ, > + > + .channels = rtw_channeltable_5g, > + .n_channels = ARRAY_SIZE(rtw_channeltable_5g), > + > + /* 5G has no CCK rates */ > + .bitrates = rtw_ratetable + 4, > + .n_bitrates = ARRAY_SIZE(rtw_ratetable) - 4, > + > + .ht_cap = {0}, > + .vht_cap = {0}, > +}; > + > +struct rtw_watch_dog_iter_data { > + struct rtw_vif *rtwvif; > + bool active; > + u8 assoc_cnt; > +}; > + > +static void rtw_vif_watch_dog_iter(void *data, u8 *mac, > + struct ieee80211_vif *vif) > +{ > + struct rtw_watch_dog_iter_data *iter_data = data; > + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; > + > + if (vif->type == NL80211_IFTYPE_STATION) { > + if (vif->bss_conf.assoc) { > + iter_data->assoc_cnt++; > + iter_data->rtwvif = rtwvif; > + } > + if (rtwvif->stats.tx_cnt > RTW_LPS_THRESHOLD || > + rtwvif->stats.rx_cnt > RTW_LPS_THRESHOLD) > + iter_data->active = true; > + } else { > + /* only STATION mode can enter lps */ > + iter_data->active = true; > + } > + > + rtwvif->stats.tx_unicast = 0; > + rtwvif->stats.rx_unicast = 0; > + rtwvif->stats.tx_cnt = 0; > + rtwvif->stats.rx_cnt = 0; > +} > + > +/* process TX/RX statistics periodically for hardware, > + * the information helps hardware to enhance performance > + */ > +static void rtw_watch_dog_work(struct work_struct *work) > +{ > + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, > + watch_dog_work.work); > + struct rtw_watch_dog_iter_data data = {}; > + > + if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING)) > + return; > + > + ieee80211_queue_delayed_work(rtwdev->hw, > &rtwdev->watch_dog_work, > + RTW_WATCH_DOG_DELAY_TIME); > + > + /* reset tx/rx statictics */ > + rtwdev->stats.tx_unicast = 0; > + rtwdev->stats.rx_unicast = 0; > + rtwdev->stats.tx_cnt = 0; > + rtwdev->stats.rx_cnt = 0; > + > + rtw_iterate_vifs(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 > + * lps, because fw does not handle the overlapped beacon interval > + */ > + if (data.rtwvif && !data.active && data.assoc_cnt == 1) > + rtw_enter_lps(rtwdev, data.rtwvif); > + > + if (rtw_flag_check(rtwdev, RTW_FLAG_SCANNING)) > + return; > + > + rtw_phy_dynamic_mechanism(rtwdev); > + > + rtwdev->watch_dog_cnt++; > +} > + > +static void rtw_c2h_work(struct work_struct *work) > +{ > + struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, c2h_work); > + struct sk_buff *skb, *tmp; > + > + skb_queue_walk_safe(&rtwdev->c2h_queue, skb, tmp) { > + skb_unlink(skb, &rtwdev->c2h_queue); > + rtw_fw_c2h_cmd_handle(rtwdev, skb); > + dev_kfree_skb_any(skb); > + } > +} > + > +void rtw_get_channel_params(struct cfg80211_chan_def *chandef, > + struct rtw_channel_params *chan_params) > +{ > + struct ieee80211_channel *channel = chandef->chan; > + enum nl80211_chan_width width = chandef->width; > + u32 primary_freq, center_freq; > + u8 center_chan; > + u8 bandwidth = RTW_CHANNEL_WIDTH_20; > + u8 primary_chan_idx = 0; > + > + center_chan = channel->hw_value; > + primary_freq = channel->center_freq; > + center_freq = chandef->center_freq1; > + > + switch (width) { > + case NL80211_CHAN_WIDTH_20_NOHT: > + case NL80211_CHAN_WIDTH_20: > + bandwidth = RTW_CHANNEL_WIDTH_20; > + primary_chan_idx = 0; > + break; > + case NL80211_CHAN_WIDTH_40: > + bandwidth = RTW_CHANNEL_WIDTH_40; > + if (primary_freq > center_freq) { > + primary_chan_idx = 1; > + center_chan -= 2; > + } else { > + primary_chan_idx = 2; > + center_chan += 2; > + } > + break; > + case NL80211_CHAN_WIDTH_80: > + bandwidth = RTW_CHANNEL_WIDTH_80; > + if (primary_freq > center_freq) { > + if (primary_freq - center_freq == 10) { > + primary_chan_idx = 1; > + center_chan -= 2; > + } else { > + primary_chan_idx = 3; > + center_chan -= 6; > + } > + } else { > + if (center_freq - primary_freq == 10) { > + primary_chan_idx = 2; > + center_chan += 2; > + } else { > + primary_chan_idx = 4; > + center_chan += 6; > + } > + } > + break; > + default: > + center_chan = 0; > + break; > + } > + > + chan_params->center_chan = center_chan; > + chan_params->bandwidth = bandwidth; > + chan_params->primary_chan_idx = primary_chan_idx; > +} > + > +void rtw_set_channel(struct rtw_dev *rtwdev) > +{ > + struct ieee80211_hw *hw = rtwdev->hw; > + struct rtw_hal *hal = &rtwdev->hal; > + struct rtw_chip_info *chip = rtwdev->chip; > + struct rtw_channel_params ch_param; > + u8 center_chan, bandwidth, primary_chan_idx; > + > + rtw_get_channel_params(&hw->conf.chandef, &ch_param); > + if (WARN(ch_param.center_chan == 0, "Invalid channel\n")) > + return; > + > + center_chan = ch_param.center_chan; > + bandwidth = ch_param.bandwidth; > + primary_chan_idx = ch_param.primary_chan_idx; > + > + hal->current_band_width = bandwidth; > + hal->current_channel = center_chan; > + hal->current_band_type = center_chan > 14 ? RTW_BAND_5G : > RTW_BAND_2G; > + chip->ops->set_channel(rtwdev, center_chan, bandwidth, > primary_chan_idx); > + > + rtw_phy_set_tx_power_level(rtwdev, center_chan); > +} > + > +static void rtw_vif_write_addr(struct rtw_dev *rtwdev, u32 start, u8 *addr) > +{ > + int i; > + > + for (i = 0; i < ETH_ALEN; i++) > + rtw_write8(rtwdev, start + i, addr[i]); > +} > + > +void rtw_vif_port_config(struct rtw_dev *rtwdev, > + struct rtw_vif *rtwvif, > + u32 config) > +{ > + u32 addr, mask; > + > + if (config & PORT_SET_MAC_ADDR) { > + addr = rtwvif->conf->mac_addr.addr; > + rtw_vif_write_addr(rtwdev, addr, rtwvif->mac_addr); > + } > + if (config & PORT_SET_BSSID) { > + addr = rtwvif->conf->bssid.addr; > + rtw_vif_write_addr(rtwdev, addr, rtwvif->bssid); > + } > + if (config & PORT_SET_NET_TYPE) { > + addr = rtwvif->conf->net_type.addr; > + mask = rtwvif->conf->net_type.mask; > + rtw_write32_mask(rtwdev, addr, mask, rtwvif->net_type); > + } > + if (config & PORT_SET_AID) { > + addr = rtwvif->conf->aid.addr; > + mask = rtwvif->conf->aid.mask; > + rtw_write32_mask(rtwdev, addr, mask, rtwvif->aid); > + } > +} > + > +static u8 hw_bw_cap_to_bitamp(u8 bw_cap) > +{ > + u8 bw = 0; > + > + switch (bw_cap) { > + case EFUSE_HW_CAP_IGNORE: > + case EFUSE_HW_CAP_SUPP_BW80: > + bw |= BIT(RTW_CHANNEL_WIDTH_80); > + /* fall through */ > + case EFUSE_HW_CAP_SUPP_BW40: > + bw |= BIT(RTW_CHANNEL_WIDTH_40); > + /* fall through */ > + default: > + bw |= BIT(RTW_CHANNEL_WIDTH_20); > + break; > + } > + > + return bw; > +} > + > +static void rtw_hw_config_rf_ant_num(struct rtw_dev *rtwdev, u8 > hw_ant_num) > +{ > + struct rtw_hal *hal = &rtwdev->hal; > + > + if (hw_ant_num == EFUSE_HW_CAP_IGNORE || > + hw_ant_num >= hal->rf_path_num) > + return; > + > + switch (hw_ant_num) { > + case 1: > + hal->rf_type = RF_1T1R; > + hal->rf_path_num = 1; > + hal->antenna_tx = BB_PATH_A; > + hal->antenna_rx = BB_PATH_A; > + break; > + default: > + WARN(1, "invalid hw configuration from efuse\n"); > + break; > + } > +} > + > +static u64 get_vht_ra_mask(struct ieee80211_sta *sta) > +{ > + u64 ra_mask = 0; > + u16 mcs_map = le16_to_cpu(sta->vht_cap.vht_mcs.rx_mcs_map); > + u8 vht_mcs_cap; > + int i, nss; > + > + /* 4SS, every two bits for MCS7/8/9 */ > + for (i = 0, nss = 12; i < 4; i++, mcs_map >>= 2, nss += 10) { > + vht_mcs_cap = mcs_map & 0x3; > + switch (vht_mcs_cap) { > + case 2: /* MCS9 */ > + ra_mask |= 0x3ff << nss; > + break; > + case 1: /* MCS8 */ > + ra_mask |= 0x1ff << nss; > + break; > + case 0: /* MCS7 */ > + ra_mask |= 0x0ff << nss; > + break; > + default: > + break; > + } > + } > + > + return ra_mask; > +} > + > +static u8 get_rate_id(u8 wireless_set, enum rtw_bandwidth bw_mode, u8 > tx_num) > +{ > + u8 rate_id = 0; > + > + switch (wireless_set) { > + case WIRELESS_CCK: > + rate_id = RTW_RATEID_B_20M; > + break; > + case WIRELESS_OFDM: > + rate_id = RTW_RATEID_G; > + break; > + case WIRELESS_CCK | WIRELESS_OFDM: > + rate_id = RTW_RATEID_BG; > + break; > + case WIRELESS_OFDM | WIRELESS_HT: > + if (tx_num == 1) > + rate_id = RTW_RATEID_GN_N1SS; > + else if (tx_num == 2) > + rate_id = RTW_RATEID_GN_N2SS; > + else if (tx_num == 3) > + rate_id = RTW_RATEID_ARFR5_N_3SS; > + break; > + case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_HT: > + if (bw_mode == RTW_CHANNEL_WIDTH_40) { > + if (tx_num == 1) > + rate_id = RTW_RATEID_BGN_40M_1SS; > + else if (tx_num == 2) > + rate_id = RTW_RATEID_BGN_40M_2SS; > + else if (tx_num == 3) > + rate_id = RTW_RATEID_ARFR5_N_3SS; > + else if (tx_num == 4) > + rate_id = RTW_RATEID_ARFR7_N_4SS; > + } else { > + if (tx_num == 1) > + rate_id = RTW_RATEID_BGN_20M_1SS; > + else if (tx_num == 2) > + rate_id = RTW_RATEID_BGN_20M_2SS; > + else if (tx_num == 3) > + rate_id = RTW_RATEID_ARFR5_N_3SS; > + else if (tx_num == 4) > + rate_id = RTW_RATEID_ARFR7_N_4SS; > + } > + break; > + case WIRELESS_OFDM | WIRELESS_VHT: > + if (tx_num == 1) > + rate_id = RTW_RATEID_ARFR1_AC_1SS; > + else if (tx_num == 2) > + rate_id = RTW_RATEID_ARFR0_AC_2SS; > + else if (tx_num == 3) > + rate_id = RTW_RATEID_ARFR4_AC_3SS; > + else if (tx_num == 4) > + rate_id = RTW_RATEID_ARFR6_AC_4SS; > + break; > + case WIRELESS_CCK | WIRELESS_OFDM | WIRELESS_VHT: > + if (bw_mode >= RTW_CHANNEL_WIDTH_80) { > + if (tx_num == 1) > + rate_id = RTW_RATEID_ARFR1_AC_1SS; > + else if (tx_num == 2) > + rate_id = RTW_RATEID_ARFR0_AC_2SS; > + else if (tx_num == 3) > + rate_id = RTW_RATEID_ARFR4_AC_3SS; > + else if (tx_num == 4) > + rate_id = RTW_RATEID_ARFR6_AC_4SS; > + } else { > + if (tx_num == 1) > + rate_id = RTW_RATEID_ARFR2_AC_2G_1SS; > + else if (tx_num == 2) > + rate_id = RTW_RATEID_ARFR3_AC_2G_2SS; > + else if (tx_num == 3) > + rate_id = RTW_RATEID_ARFR4_AC_3SS; > + else if (tx_num == 4) > + rate_id = RTW_RATEID_ARFR6_AC_4SS; > + } > + break; > + default: > + break; > + } > + > + return rate_id; > +} > + > +#define RA_MASK_CCK_RATES 0x0000f > +#define RA_MASK_OFDM_RATES 0x00ff0 > +#define RA_MASK_HT_RATES_1SS (0xff000 << 0) > +#define RA_MASK_HT_RATES_2SS (0xff000 << 8) > +#define RA_MASK_HT_RATES_3SS (0xff000 << 16) > +#define RA_MASK_HT_RATES (RA_MASK_HT_RATES_1SS | \ > + RA_MASK_HT_RATES_2SS | \ > + RA_MASK_HT_RATES_3SS) > +#define RA_MASK_VHT_RATES_1SS (0x3ff000 << 0) > +#define RA_MASK_VHT_RATES_2SS (0x3ff000 << 10) > +#define RA_MASK_VHT_RATES_3SS (0x3ff000 << 20) > +#define RA_MASK_VHT_RATES (RA_MASK_VHT_RATES_1SS | \ > + RA_MASK_VHT_RATES_2SS | \ > + RA_MASK_VHT_RATES_3SS) > +#define RA_MASK_CCK_IN_HT 0x00005 > +#define RA_MASK_CCK_IN_VHT 0x00005 > +#define RA_MASK_OFDM_IN_VHT 0x00010 > +#define RA_MASK_OFDM_IN_HT_2G 0x00010 > +#define RA_MASK_OFDM_IN_HT_5G 0x00030 > + > +void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) > +{ > + struct ieee80211_sta *sta = si->sta; > + struct rtw_efuse *efuse = &rtwdev->efuse; > + struct rtw_hal *hal = &rtwdev->hal; > + u8 rssi_level; > + u8 wireless_set; > + u8 bw_mode; > + u8 rate_id; > + u8 rf_type = RF_1T1R; > + u8 stbc_en = 0; > + u8 ldpc_en = 0; > + u8 tx_num = 1; > + u64 ra_mask = 0; > + bool is_vht_enable = false; > + bool is_support_sgi = false; > + > + if (sta->vht_cap.vht_supported) { > + is_vht_enable = true; > + ra_mask |= get_vht_ra_mask(sta); > + if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXSTBC_MASK) > + stbc_en = VHT_STBC_EN; > + if (sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC) > + ldpc_en = VHT_LDPC_EN; > + if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) > + is_support_sgi = true; > + } else if (sta->ht_cap.ht_supported) { > + ra_mask |= (sta->ht_cap.mcs.rx_mask[NL80211_BAND_5GHZ] << 20) > | > + (sta->ht_cap.mcs.rx_mask[NL80211_BAND_2GHZ] << 12); > + if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) > + stbc_en = HT_STBC_EN; > + if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) > + ldpc_en = HT_LDPC_EN; > + if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20 || > + sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) > + is_support_sgi = true; > + } > + > + if (hal->current_band_type == RTW_BAND_5G) { > + ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4; > + if (sta->vht_cap.vht_supported) { > + ra_mask &= RA_MASK_VHT_RATES | RA_MASK_OFDM_IN_VHT; > + wireless_set = WIRELESS_OFDM | WIRELESS_VHT; > + } else if (sta->ht_cap.ht_supported) { > + ra_mask &= RA_MASK_HT_RATES | > RA_MASK_OFDM_IN_HT_5G; > + wireless_set = WIRELESS_OFDM | WIRELESS_HT; > + } else { > + wireless_set = WIRELESS_OFDM; > + } > + } else if (hal->current_band_type == RTW_BAND_2G) { > + ra_mask |= sta->supp_rates[NL80211_BAND_2GHZ]; > + if (sta->vht_cap.vht_supported) { > + ra_mask &= RA_MASK_VHT_RATES | RA_MASK_CCK_IN_VHT | > + RA_MASK_OFDM_IN_VHT; > + wireless_set = WIRELESS_CCK | WIRELESS_OFDM | > + WIRELESS_HT | WIRELESS_VHT; > + } else if (sta->ht_cap.ht_supported) { > + ra_mask &= RA_MASK_HT_RATES | RA_MASK_CCK_IN_HT | > + RA_MASK_OFDM_IN_HT_2G; > + wireless_set = WIRELESS_CCK | WIRELESS_OFDM | > + WIRELESS_HT; > + } else if (sta->supp_rates[0] <= 0xf) { > + wireless_set = WIRELESS_CCK; > + } else { > + wireless_set = WIRELESS_CCK | WIRELESS_OFDM; > + } > + } else { > + rtw_err(rtwdev, "Unknown band type\n"); > + wireless_set = 0; > + } > + > + if (efuse->hw_cap.nss == 1) { > + ra_mask &= RA_MASK_VHT_RATES_1SS; > + ra_mask &= RA_MASK_HT_RATES_1SS; > + } > + > + switch (sta->bandwidth) { > + case IEEE80211_STA_RX_BW_80: > + bw_mode = RTW_CHANNEL_WIDTH_80; > + break; > + case IEEE80211_STA_RX_BW_40: > + bw_mode = RTW_CHANNEL_WIDTH_40; > + break; > + default: > + bw_mode = RTW_CHANNEL_WIDTH_20; > + break; > + } > + > + if (sta->vht_cap.vht_supported && ra_mask & 0xffc00000) { > + tx_num = 2; > + rf_type = RF_2T2R; > + } else if (sta->ht_cap.ht_supported && ra_mask & 0xfff00000) { > + tx_num = 2; > + rf_type = RF_2T2R; > + } > + > + rate_id = get_rate_id(wireless_set, bw_mode, tx_num); > + > + if (wireless_set != WIRELESS_CCK) { > + rssi_level = si->rssi_level; > + if (rssi_level == 0) > + ra_mask &= 0xffffffffffffffffULL; > + else if (rssi_level == 1) > + ra_mask &= 0xfffffffffffffff0ULL; > + else if (rssi_level == 2) > + ra_mask &= 0xffffffffffffefe0ULL; > + else if (rssi_level == 3) > + ra_mask &= 0xffffffffffffcfc0ULL; > + else if (rssi_level == 4) > + ra_mask &= 0xffffffffffff8f80ULL; > + else if (rssi_level >= 5) > + ra_mask &= 0xffffffffffff0f00ULL; > + } > + > + si->bw_mode = bw_mode; > + si->stbc_en = stbc_en; > + si->ldpc_en = ldpc_en; > + si->rf_type = rf_type; > + si->wireless_set = wireless_set; > + si->sgi_enable = is_support_sgi; > + si->vht_enable = is_vht_enable; > + si->ra_mask = ra_mask; > + si->rate_id = rate_id; > + > + rtw_fw_send_ra_info(rtwdev, si); > +} > + > +static int rtw_power_on(struct rtw_dev *rtwdev) > +{ > + struct rtw_chip_info *chip = rtwdev->chip; > + struct rtw_fw_state *fw = &rtwdev->fw; > + int ret; > + > + ret = rtw_hci_setup(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to setup hci\n"); > + goto err; > + } > + > + /* power on MAC before firmware downloaded */ > + ret = rtw_mac_power_on(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to power on mac\n"); > + goto err; > + } > + > + wait_for_completion(&fw->completion); > + if (!fw->firmware) { > + ret = -EINVAL; > + rtw_err(rtwdev, "failed to load firmware\n"); > + goto err; > + } > + > + ret = rtw_download_firmware(rtwdev, fw->firmware->data, > + fw->firmware->size); > + if (ret) { > + rtw_err(rtwdev, "failed to download firmware\n"); > + goto err_off; > + } > + > + /* config mac after firmware downloaded */ > + ret = rtw_mac_init(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to configure mac\n"); > + goto err_off; > + } > + > + chip->ops->phy_set_param(rtwdev); > + > + ret = rtw_hci_start(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to start hci\n"); > + goto err_off; > + } > + > + return 0; > + > +err_off: > + rtw_mac_power_off(rtwdev); > + > +err: > + return ret; > +} > + > +int rtw_core_start(struct rtw_dev *rtwdev) > +{ > + int ret; > + > + ret = rtw_power_on(rtwdev); > + if (ret) > + return ret; > + > + rtwdev->h2c.last_box_num = 0; > + > + rtw_sec_enable_sec_engine(rtwdev); > + > + /* rcr reset after powered on */ > + rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr); > + > + ieee80211_queue_delayed_work(rtwdev->hw, > &rtwdev->watch_dog_work, > + RTW_WATCH_DOG_DELAY_TIME); > + > + rtw_flag_set(rtwdev, RTW_FLAG_RUNNING); > + > + return 0; > +} > + > +static void rtw_power_off(struct rtw_dev *rtwdev) > +{ > + rtwdev->hci.ops->stop(rtwdev); > + rtw_mac_power_off(rtwdev); > +} > + > +void rtw_core_stop(struct rtw_dev *rtwdev) > +{ > + rtw_flag_clear(rtwdev, RTW_FLAG_RUNNING); > + rtw_flag_clear(rtwdev, RTW_FLAG_FW_RUNNING); > + > + cancel_delayed_work_sync(&rtwdev->watch_dog_work); > + > + rtw_power_off(rtwdev); > +} > + > +static void rtw_init_ht_cap(struct rtw_dev *rtwdev, > + struct ieee80211_sta_ht_cap *ht_cap) > +{ > + struct rtw_efuse *efuse = &rtwdev->efuse; > + > + ht_cap->ht_supported = true; > + ht_cap->cap = 0; > + ht_cap->cap |= IEEE80211_HT_CAP_SGI_20 | > + IEEE80211_HT_CAP_MAX_AMSDU | > + IEEE80211_HT_CAP_LDPC_CODING | > + (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); > + if (efuse->hw_cap.bw & BIT(RTW_CHANNEL_WIDTH_40)) > + ht_cap->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40 | > + IEEE80211_HT_CAP_DSSSCCK40 | > + IEEE80211_HT_CAP_SGI_40; > + ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; > + ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; > + ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; > + if (efuse->hw_cap.nss > 1) { > + ht_cap->mcs.rx_mask[0] = 0xFF; > + ht_cap->mcs.rx_mask[1] = 0xFF; > + ht_cap->mcs.rx_mask[4] = 0x01; > + ht_cap->mcs.rx_highest = cpu_to_le16(300); > + } else { > + ht_cap->mcs.rx_mask[0] = 0xFF; > + ht_cap->mcs.rx_mask[1] = 0x00; > + ht_cap->mcs.rx_mask[4] = 0x01; > + ht_cap->mcs.rx_highest = cpu_to_le16(150); > + } > +} > + > +static void rtw_init_vht_cap(struct rtw_dev *rtwdev, > + struct ieee80211_sta_vht_cap *vht_cap) > +{ > + struct rtw_efuse *efuse = &rtwdev->efuse; > + u16 mcs_map; > + __le16 highest; > + > + if (efuse->hw_cap.ptcl != EFUSE_HW_CAP_IGNORE && > + efuse->hw_cap.ptcl != EFUSE_HW_CAP_PTCL_VHT) > + return; > + > + vht_cap->vht_supported = true; > + vht_cap->cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | > + IEEE80211_VHT_CAP_RXLDPC | > + IEEE80211_VHT_CAP_SHORT_GI_80 | > + IEEE80211_VHT_CAP_TXSTBC | > + IEEE80211_VHT_CAP_RXSTBC_1 | > + IEEE80211_VHT_CAP_HTC_VHT | > + > IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | > + 0; > + mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | > + IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | > + IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | > + IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | > + IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | > + IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | > + IEEE80211_VHT_MCS_NOT_SUPPORTED << 14; > + if (efuse->hw_cap.nss > 1) { > + highest = cpu_to_le16(780); > + mcs_map |= IEEE80211_VHT_MCS_SUPPORT_0_9 << 2; > + } else { > + highest = cpu_to_le16(390); > + mcs_map |= IEEE80211_VHT_MCS_NOT_SUPPORTED << 2; > + } > + > + vht_cap->vht_mcs.rx_mcs_map = cpu_to_le16(mcs_map); > + vht_cap->vht_mcs.tx_mcs_map = cpu_to_le16(mcs_map); > + vht_cap->vht_mcs.rx_highest = highest; > + vht_cap->vht_mcs.tx_highest = highest; > +} > + > +static void rtw_set_supported_band(struct ieee80211_hw *hw, > + struct rtw_chip_info *chip) > +{ > + struct rtw_dev *rtwdev = hw->priv; > + struct ieee80211_supported_band *sband; > + > + if (chip->band & RTW_BAND_2G) { > + sband = kmemdup(&rtw_band_2ghz, sizeof(*sband), GFP_KERNEL); > + if (!sband) > + goto err_out; > + if (chip->ht_supported) > + rtw_init_ht_cap(rtwdev, &sband->ht_cap); > + hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; > + } > + > + if (chip->band & RTW_BAND_5G) { > + sband = kmemdup(&rtw_band_5ghz, sizeof(*sband), GFP_KERNEL); > + if (!sband) > + goto err_out; > + if (chip->ht_supported) > + rtw_init_ht_cap(rtwdev, &sband->ht_cap); > + if (chip->vht_supported) > + rtw_init_vht_cap(rtwdev, &sband->vht_cap); > + hw->wiphy->bands[NL80211_BAND_5GHZ] = sband; > + } > + > + return; > + > +err_out: > + rtw_err(rtwdev, "failed to set supported band\n"); > + kfree(sband); > + return; > +} > + > +static void rtw_unset_supported_band(struct ieee80211_hw *hw, > + struct rtw_chip_info *chip) > +{ > + kfree(hw->wiphy->bands[NL80211_BAND_2GHZ]); > + kfree(hw->wiphy->bands[NL80211_BAND_5GHZ]); > +} > + > +static void rtw_load_firmware_cb(const struct firmware *firmware, void > *context) > +{ > + struct rtw_dev *rtwdev = context; > + struct rtw_fw_state *fw = &rtwdev->fw; > + > + if (!firmware) > + rtw_err(rtwdev, "failed to request firmware\n"); > + > + fw->firmware = firmware; > + complete_all(&fw->completion); > +} > + > +static int rtw_load_firmware(struct rtw_dev *rtwdev, const char *fw_name) > +{ > + struct rtw_fw_state *fw = &rtwdev->fw; > + int ret; > + > + init_completion(&fw->completion); > + > + ret = request_firmware_nowait(THIS_MODULE, true, fw_name, > rtwdev->dev, > + GFP_KERNEL, rtwdev, rtw_load_firmware_cb); > + if (ret) { > + rtw_err(rtwdev, "async firmware request failed\n"); > + return ret; > + } > + > + return 0; > +} > + > +static int rtw_chip_parameter_setup(struct rtw_dev *rtwdev) > +{ > + struct rtw_chip_info *chip = rtwdev->chip; > + struct rtw_hal *hal = &rtwdev->hal; > + struct rtw_efuse *efuse = &rtwdev->efuse; > + u32 wl_bt_pwr_ctrl; > + int ret = 0; > + > + switch (rtw_hci_type(rtwdev)) { > + case RTW_HCI_TYPE_PCIE: > + rtwdev->hci.rpwm_addr = 0x03d9; > + break; > + default: > + rtw_err(rtwdev, "unsupported hci type\n"); > + return -EINVAL; > + } > + > + wl_bt_pwr_ctrl = rtw_read32(rtwdev, REG_WL_BT_PWR_CTRL); > + if (wl_bt_pwr_ctrl & BIT_BT_FUNC_EN) > + rtwdev->efuse.btcoex = true; > + hal->chip_version = rtw_read32(rtwdev, REG_SYS_CFG1); > + hal->fab_version = BIT_GET_VENDOR_ID(hal->chip_version) >> 2; > + hal->cut_version = BIT_GET_CHIP_VER(hal->chip_version); > + hal->mp_chip = (hal->chip_version & BIT_RTL_ID) ? 0 : 1; > + if (hal->chip_version & BIT_RF_TYPE_ID) { > + hal->rf_type = RF_2T2R; > + hal->rf_path_num = 2; > + hal->antenna_tx = BB_PATH_AB; > + hal->antenna_rx = BB_PATH_AB; > + } else { > + hal->rf_type = RF_1T1R; > + hal->rf_path_num = 1; > + hal->antenna_tx = BB_PATH_A; > + hal->antenna_rx = BB_PATH_A; > + } > + > + if (hal->fab_version == 2) > + hal->fab_version = 1; > + else if (hal->fab_version == 1) > + hal->fab_version = 2; > + > + efuse->physical_size = chip->phy_efuse_size; > + efuse->logical_size = chip->log_efuse_size; > + efuse->protect_size = chip->ptct_efuse_size; > + > + /* default use ack */ > + rtwdev->hal.rcr |= BIT_VHT_DACK; > + > + return ret; > +} > + > +static int rtw_chip_efuse_enable(struct rtw_dev *rtwdev) > +{ > + struct rtw_fw_state *fw = &rtwdev->fw; > + int ret; > + > + ret = rtw_hci_setup(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to setup hci\n"); > + goto err; > + } > + > + ret = rtw_mac_power_on(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to power on mac\n"); > + goto err; > + } > + > + rtw_write8(rtwdev, REG_C2HEVT, C2H_HW_FEATURE_DUMP); > + ret = rtw_download_firmware(rtwdev, fw->firmware->data, > + fw->firmware->size); > + if (ret) { > + rtw_err(rtwdev, "failed to download firmware\n"); > + goto err_off; > + } > + > + return 0; > + > +err_off: > + rtw_mac_power_off(rtwdev); > + > +err: > + return ret; > +} > + > +static int rtw_dump_hw_feature(struct rtw_dev *rtwdev) > +{ > + struct rtw_efuse *efuse = &rtwdev->efuse; > + struct efuse_hw_cap *hw_cap; > + u8 hw_feature[HW_FEATURE_LEN]; > + u8 id; > + int i; > + > + BUILD_BUG_ON(sizeof(*hw_cap) != HW_FEATURE_LEN); > + > + id = rtw_read8(rtwdev, REG_C2HEVT); > + if (id != C2H_HW_FEATURE_REPORT) { > + rtw_err(rtwdev, "failed to read hw feature report\n"); > + return -EBUSY; > + } > + > + for (i = 0; i < HW_FEATURE_LEN; i++) > + hw_feature[i] = rtw_read8(rtwdev, REG_C2HEVT + 2 + i); > + > + rtw_write8(rtwdev, REG_C2HEVT, 0); > + > + hw_cap = (struct efuse_hw_cap *)hw_feature; > + > + efuse->hw_cap.bw = hw_bw_cap_to_bitamp(hw_cap->bw); > + efuse->hw_cap.hci = hw_cap->hci; > + efuse->hw_cap.nss = hw_cap->nss; > + efuse->hw_cap.ptcl = hw_cap->ptcl; > + efuse->hw_cap.ant_num = hw_cap->ant_num; > + > + rtw_hw_config_rf_ant_num(rtwdev, efuse->hw_cap.ant_num); > + > + if (efuse->hw_cap.nss == EFUSE_HW_CAP_IGNORE) > + efuse->hw_cap.nss = rtwdev->hal.rf_path_num; > + > + rtw_dbg(rtwdev, "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, > ant_num=%d, nss=%d\n", > + efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, > + efuse->hw_cap.ant_num, efuse->hw_cap.nss); > + > + return 0; > +} > + > +static void rtw_chip_efuse_disable(struct rtw_dev *rtwdev) > +{ > + rtw_hci_stop(rtwdev); > + rtw_mac_power_off(rtwdev); > +} > + > +static int rtw_chip_efuse_info_setup(struct rtw_dev *rtwdev) > +{ > + struct rtw_efuse *efuse = &rtwdev->efuse; > + int ret; > + > + mutex_lock(&rtwdev->mutex); > + > + /* power on mac to read efuse */ > + ret = rtw_chip_efuse_enable(rtwdev); > + if (ret) > + goto out; > + > + ret = rtw_parse_efuse_map(rtwdev); > + if (ret) > + goto out; > + > + ret = rtw_dump_hw_feature(rtwdev); > + if (ret) > + goto out; > + > + ret = rtw_check_supported_rfe(rtwdev); > + if (ret) > + goto out; > + > + if (efuse->crystal_cap == 0xff) > + efuse->crystal_cap = 0; > + if (efuse->pa_type_2g == 0xff) > + efuse->pa_type_2g = 0; > + if (efuse->pa_type_5g == 0xff) > + efuse->pa_type_5g = 0; > + if (efuse->lna_type_2g == 0xff) > + efuse->lna_type_2g = 0; > + if (efuse->lna_type_5g == 0xff) > + efuse->lna_type_5g = 0; > + if (efuse->channel_plan == 0xff) > + efuse->channel_plan = 0x7f; > + if (efuse->bt_setting & BIT(0)) > + efuse->share_ant = true; > + if (efuse->regd == 0xff) > + efuse->regd = 0; > + > + efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0; > + efuse->ext_lna_2g = efuse->lna_type_2g & BIT(3) ? 1 : 0; > + efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0; > + efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0; > + > + rtw_chip_efuse_disable(rtwdev); > + > +out: > + mutex_unlock(&rtwdev->mutex); > + return ret; > +} > + > +static int rtw_chip_board_info_setup(struct rtw_dev *rtwdev) > +{ > + struct rtw_hal *hal = &rtwdev->hal; > + const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); > + > + if (!rfe_def) > + return -ENODEV; > + > + rtw_phy_setup_phy_cond(rtwdev, 0); > + > + rtw_hw_init_tx_power(hal); > + if (rtwdev->chip->id != RTW_CHIP_TYPE_8822C) > + 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); > + rtw_phy_tx_power_limit_config(hal); > + > + return 0; > +} > + > +int rtw_chip_info_setup(struct rtw_dev *rtwdev) > +{ > + int ret; > + > + ret = rtw_chip_parameter_setup(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to setup chip parameters\n"); > + goto err_out; > + } > + > + ret = rtw_chip_efuse_info_setup(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to setup chip efuse info\n"); > + goto err_out; > + } > + > + ret = rtw_chip_board_info_setup(rtwdev); > + if (ret) { > + rtw_err(rtwdev, "failed to setup chip board info\n"); > + goto err_out; > + } > + > + return 0; > + > +err_out: > + return ret; > +} > +EXPORT_SYMBOL(rtw_chip_info_setup); > + > +int rtw_core_init(struct rtw_dev *rtwdev) > +{ > + int ret; > + > + INIT_LIST_HEAD(&rtwdev->rsvd_page_list); > + > + INIT_DELAYED_WORK(&rtwdev->watch_dog_work, > rtw_watch_dog_work); > + INIT_DELAYED_WORK(&rtwdev->lps_work, rtw_lps_work); > + INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work); > + skb_queue_head_init(&rtwdev->c2h_queue); > + > + spin_lock_init(&rtwdev->dm_lock); > + spin_lock_init(&rtwdev->rf_lock); > + spin_lock_init(&rtwdev->h2c.lock); > + > + mutex_init(&rtwdev->mutex); > + mutex_init(&rtwdev->hal.tx_power_mutex); > + > + rtwdev->sec.total_cam_num = 32; > + rtwdev->hal.current_channel = 1; > + set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map); > + > + mutex_lock(&rtwdev->mutex); > + rtw_add_rsvd_page(rtwdev, RSVD_BEACON, false); > + mutex_unlock(&rtwdev->mutex); > + > + /* default rx filter setting */ > + rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV | > + BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | > + BIT_AB | BIT_AM | BIT_APM; > + > + ret = rtw_load_firmware(rtwdev, rtwdev->chip->fw_name); > + if (ret) { > + rtw_warn(rtwdev, "no firmware loaded\n"); > + return ret; > + } > + > + return 0; > +} > +EXPORT_SYMBOL(rtw_core_init); > + > +void rtw_core_deinit(struct rtw_dev *rtwdev) > +{ > + struct rtw_fw_state *fw = &rtwdev->fw; > + struct rtw_rsvd_page *rsvd_pkt, *tmp; > + > + if (fw->firmware) > + release_firmware(fw->firmware); > + > + list_for_each_entry_safe(rsvd_pkt, tmp, &rtwdev->rsvd_page_list, list) { > + list_del(&rsvd_pkt->list); > + kfree(rsvd_pkt); > + } > + > + mutex_destroy(&rtwdev->mutex); > + mutex_destroy(&rtwdev->hal.tx_power_mutex); > +} > +EXPORT_SYMBOL(rtw_core_deinit); > + > +int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) > +{ > + int max_tx_headroom = 0; > + int ret; > + > + /* TODO: USB & SDIO may need extra room? */ > + max_tx_headroom = rtwdev->chip->tx_pkt_desc_sz; > + > + hw->extra_tx_headroom = max_tx_headroom; > + hw->queues = IEEE80211_NUM_ACS; > + hw->sta_data_size = sizeof(struct rtw_sta_info); > + hw->vif_data_size = sizeof(struct rtw_vif); > + > + ieee80211_hw_set(hw, SIGNAL_DBM); > + ieee80211_hw_set(hw, RX_INCLUDES_FCS); > + ieee80211_hw_set(hw, AMPDU_AGGREGATION); > + ieee80211_hw_set(hw, MFP_CAPABLE); > + ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); > + ieee80211_hw_set(hw, SUPPORTS_PS); > + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); > + > + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | > + BIT(NL80211_IFTYPE_AP) | > + BIT(NL80211_IFTYPE_ADHOC) | > + BIT(NL80211_IFTYPE_MESH_POINT); > + > + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | > + WIPHY_FLAG_TDLS_EXTERNAL_SETUP; > + > + rtw_set_supported_band(hw, rtwdev->chip); > + SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr); > + > + rtw_regd_init(rtwdev, rtw_regd_notifier); > + > + ret = ieee80211_register_hw(hw); > + if (ret) { > + rtw_err(rtwdev, "failed to register hw\n"); > + return ret; > + } > + > + if (regulatory_hint(hw->wiphy, rtwdev->regd.alpha2)) > + rtw_err(rtwdev, "regulatory_hint fail\n"); > + > + rtw_debugfs_init(rtwdev); > + > + return 0; > +} > +EXPORT_SYMBOL(rtw_register_hw); > + > +void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) > +{ > + struct rtw_chip_info *chip = rtwdev->chip; > + > + ieee80211_unregister_hw(hw); > + rtw_unset_supported_band(hw, chip); > +} > +EXPORT_SYMBOL(rtw_unregister_hw); > + > +MODULE_AUTHOR("Realtek Corporation"); > +MODULE_DESCRIPTION("Realtek 802.11ac wireless core module"); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/net/wireless/realtek/rtw88/main.h > b/drivers/net/wireless/realtek/rtw88/main.h > new file mode 100644 > index 0000000..b345fe0 > --- /dev/null > +++ b/drivers/net/wireless/realtek/rtw88/main.h > @@ -0,0 +1,1119 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* Copyright(c) 2018 Realtek Corporation. > + */ > + > +#ifndef __RTK_MAIN_H_ > +#define __RTK_MAIN_H_ > + > +#include <net/mac80211.h> > +#include <linux/vmalloc.h> > +#include <linux/firmware.h> > +#include <linux/average.h> > +#include <linux/bitops.h> > +#include <linux/bitfield.h> > + > +#define RTW_MAX_MAC_ID_NUM 32 > +#define RTW_MAX_SEC_CAM_NUM 32 > + > +#define RTW_WATCH_DOG_DELAY_TIME round_jiffies_relative(HZ * 2) > + > +#define RFREG_MASK 0xfffff > +#define INV_RF_DATA 0xffffffff > +#define TX_PAGE_SIZE_SHIFT 7 > + > +#define RTW_CHANNEL_WIDTH_MAX 3 > +#define RTW_RF_PATH_MAX 4 > +#define HW_FEATURE_LEN 13 > + > +extern const struct ieee80211_ops rtw_ops; > +extern struct rtw_chip_info rtw8822b_hw_spec; > +extern struct rtw_chip_info rtw8822c_hw_spec; > + > +#define RTW_MAX_CHANNEL_NUM_2G 14 > +#define RTW_MAX_CHANNEL_NUM_5G 49 > + > +struct rtw_dev; > + > +enum rtw_hci_type { > + RTW_HCI_TYPE_PCIE, > + RTW_HCI_TYPE_USB, > + RTW_HCI_TYPE_SDIO, > + > + RTW_HCI_TYPE_UNDEFINE, > +}; > + > +struct rtw_hci { > + struct rtw_hci_ops *ops; > + enum rtw_hci_type type; > + > + u32 rpwm_addr; > + > + u8 bulkout_num; > +}; > + > +enum rtw_supported_band { > + RTW_BAND_2G = 1 << 0, > + RTW_BAND_5G = 1 << 1, > + RTW_BAND_60G = 1 << 2, > + > + RTW_BAND_MAX, > +}; > + > +enum rtw_bandwidth { > + RTW_CHANNEL_WIDTH_20 = 0, > + RTW_CHANNEL_WIDTH_40 = 1, > + RTW_CHANNEL_WIDTH_80 = 2, > + RTW_CHANNEL_WIDTH_160 = 3, > + RTW_CHANNEL_WIDTH_80_80 = 4, > + RTW_CHANNEL_WIDTH_5 = 5, > + RTW_CHANNEL_WIDTH_10 = 6, > +}; > + > +enum rtw_net_type { > + RTW_NET_NO_LINK = 0, > + RTW_NET_AD_HOC = 1, > + RTW_NET_MGD_LINKED = 2, > + RTW_NET_AP_MODE = 3, > +}; > + > +enum rtw_rf_type { > + RF_1T1R = 0, > + RF_1T2R = 1, > + RF_2T2R = 2, > + RF_2T3R = 3, > + RF_2T4R = 4, > + RF_3T3R = 5, > + RF_3T4R = 6, > + RF_4T4R = 7, > + RF_TYPE_MAX, > +}; > + > +enum rtw_rf_path { > + RF_PATH_A = 0, > + RF_PATH_B = 1, > + RF_PATH_C = 2, > + RF_PATH_D = 3, > +}; > + > +enum rtw_bb_path { > + BB_PATH_A = BIT(0), > + BB_PATH_B = BIT(1), > + BB_PATH_C = BIT(2), > + BB_PATH_D = BIT(3), > + > + BB_PATH_AB = (BB_PATH_A | BB_PATH_B), > + BB_PATH_AC = (BB_PATH_A | BB_PATH_C), > + BB_PATH_AD = (BB_PATH_A | BB_PATH_D), > + BB_PATH_BC = (BB_PATH_B | BB_PATH_C), > + BB_PATH_BD = (BB_PATH_B | BB_PATH_D), > + BB_PATH_CD = (BB_PATH_C | BB_PATH_D), > + > + BB_PATH_ABC = (BB_PATH_A | BB_PATH_B | BB_PATH_C), > + BB_PATH_ABD = (BB_PATH_A | BB_PATH_B | BB_PATH_D), > + BB_PATH_ACD = (BB_PATH_A | BB_PATH_C | BB_PATH_D), > + BB_PATH_BCD = (BB_PATH_B | BB_PATH_C | BB_PATH_D), > + > + BB_PATH_ABCD = (BB_PATH_A | BB_PATH_B | BB_PATH_C | BB_PATH_D), > +}; > + > +enum rtw_rate_section { > + RTW_RATE_SECTION_CCK = 0, > + RTW_RATE_SECTION_OFDM, > + RTW_RATE_SECTION_HT_1S, > + RTW_RATE_SECTION_HT_2S, > + RTW_RATE_SECTION_VHT_1S, > + RTW_RATE_SECTION_VHT_2S, > + > + /* keep last */ > + RTW_RATE_SECTION_MAX, > +}; > + > +enum rtw_wireless_set { > + WIRELESS_CCK = 0x00000001, > + WIRELESS_OFDM = 0x00000002, > + WIRELESS_HT = 0x00000004, > + WIRELESS_VHT = 0x00000008, > +}; > + > +#define HT_STBC_EN BIT(0) > +#define VHT_STBC_EN BIT(1) > +#define HT_LDPC_EN BIT(0) > +#define VHT_LDPC_EN BIT(1) > + > +enum rtw_chip_type { > + RTW_CHIP_TYPE_8822B, > + RTW_CHIP_TYPE_8822C, > +}; > + > +enum rtw_tx_queue_type { > + /* the order of AC queues matters */ > + RTW_TX_QUEUE_BK = 0x0, > + RTW_TX_QUEUE_BE = 0x1, > + RTW_TX_QUEUE_VI = 0x2, > + RTW_TX_QUEUE_VO = 0x3, > + > + RTW_TX_QUEUE_BCN = 0x4, > + RTW_TX_QUEUE_MGMT = 0x5, > + RTW_TX_QUEUE_HI0 = 0x6, > + RTW_TX_QUEUE_H2C = 0x7, > + /* keep it last */ > + RTK_MAX_TX_QUEUE_NUM > +}; > + > +enum rtw_rx_queue_type { > + RTW_RX_QUEUE_MPDU = 0x0, > + RTW_RX_QUEUE_C2H = 0x1, > + /* keep it last */ > + RTK_MAX_RX_QUEUE_NUM > +}; > + > +enum rtw_rate_index { > + RTW_RATEID_BGN_40M_2SS = 0, > + RTW_RATEID_BGN_40M_1SS = 1, > + RTW_RATEID_BGN_20M_2SS = 2, > + RTW_RATEID_BGN_20M_1SS = 3, > + RTW_RATEID_GN_N2SS = 4, > + RTW_RATEID_GN_N1SS = 5, > + RTW_RATEID_BG = 6, > + RTW_RATEID_G = 7, > + RTW_RATEID_B_20M = 8, > + RTW_RATEID_ARFR0_AC_2SS = 9, > + RTW_RATEID_ARFR1_AC_1SS = 10, > + RTW_RATEID_ARFR2_AC_2G_1SS = 11, > + RTW_RATEID_ARFR3_AC_2G_2SS = 12, > + RTW_RATEID_ARFR4_AC_3SS = 13, > + RTW_RATEID_ARFR5_N_3SS = 14, > + RTW_RATEID_ARFR7_N_4SS = 15, > + RTW_RATEID_ARFR6_AC_4SS = 16 > +}; > + > +enum rtw_trx_desc_rate { > + DESC_RATE1M = 0x00, > + DESC_RATE2M = 0x01, > + DESC_RATE5_5M = 0x02, > + DESC_RATE11M = 0x03, > + > + DESC_RATE6M = 0x04, > + DESC_RATE9M = 0x05, > + DESC_RATE12M = 0x06, > + DESC_RATE18M = 0x07, > + DESC_RATE24M = 0x08, > + DESC_RATE36M = 0x09, > + DESC_RATE48M = 0x0a, > + DESC_RATE54M = 0x0b, > + > + DESC_RATEMCS0 = 0x0c, > + DESC_RATEMCS1 = 0x0d, > + DESC_RATEMCS2 = 0x0e, > + DESC_RATEMCS3 = 0x0f, > + DESC_RATEMCS4 = 0x10, > + DESC_RATEMCS5 = 0x11, > + DESC_RATEMCS6 = 0x12, > + DESC_RATEMCS7 = 0x13, > + DESC_RATEMCS8 = 0x14, > + DESC_RATEMCS9 = 0x15, > + DESC_RATEMCS10 = 0x16, > + DESC_RATEMCS11 = 0x17, > + DESC_RATEMCS12 = 0x18, > + DESC_RATEMCS13 = 0x19, > + DESC_RATEMCS14 = 0x1a, > + DESC_RATEMCS15 = 0x1b, > + DESC_RATEMCS16 = 0x1c, > + DESC_RATEMCS17 = 0x1d, > + DESC_RATEMCS18 = 0x1e, > + DESC_RATEMCS19 = 0x1f, > + DESC_RATEMCS20 = 0x20, > + DESC_RATEMCS21 = 0x21, > + DESC_RATEMCS22 = 0x22, > + DESC_RATEMCS23 = 0x23, > + DESC_RATEMCS24 = 0x24, > + DESC_RATEMCS25 = 0x25, > + DESC_RATEMCS26 = 0x26, > + DESC_RATEMCS27 = 0x27, > + DESC_RATEMCS28 = 0x28, > + DESC_RATEMCS29 = 0x29, > + DESC_RATEMCS30 = 0x2a, > + DESC_RATEMCS31 = 0x2b, > + > + DESC_RATEVHT1SS_MCS0 = 0x2c, > + DESC_RATEVHT1SS_MCS1 = 0x2d, > + DESC_RATEVHT1SS_MCS2 = 0x2e, > + DESC_RATEVHT1SS_MCS3 = 0x2f, > + DESC_RATEVHT1SS_MCS4 = 0x30, > + DESC_RATEVHT1SS_MCS5 = 0x31, > + DESC_RATEVHT1SS_MCS6 = 0x32, > + DESC_RATEVHT1SS_MCS7 = 0x33, > + DESC_RATEVHT1SS_MCS8 = 0x34, > + DESC_RATEVHT1SS_MCS9 = 0x35, > + > + DESC_RATEVHT2SS_MCS0 = 0x36, > + DESC_RATEVHT2SS_MCS1 = 0x37, > + DESC_RATEVHT2SS_MCS2 = 0x38, > + DESC_RATEVHT2SS_MCS3 = 0x39, > + DESC_RATEVHT2SS_MCS4 = 0x3a, > + DESC_RATEVHT2SS_MCS5 = 0x3b, > + DESC_RATEVHT2SS_MCS6 = 0x3c, > + DESC_RATEVHT2SS_MCS7 = 0x3d, > + DESC_RATEVHT2SS_MCS8 = 0x3e, > + DESC_RATEVHT2SS_MCS9 = 0x3f, > + > + DESC_RATEVHT3SS_MCS0 = 0x40, > + DESC_RATEVHT3SS_MCS1 = 0x41, > + DESC_RATEVHT3SS_MCS2 = 0x42, > + DESC_RATEVHT3SS_MCS3 = 0x43, > + DESC_RATEVHT3SS_MCS4 = 0x44, > + DESC_RATEVHT3SS_MCS5 = 0x45, > + DESC_RATEVHT3SS_MCS6 = 0x46, > + DESC_RATEVHT3SS_MCS7 = 0x47, > + DESC_RATEVHT3SS_MCS8 = 0x48, > + DESC_RATEVHT3SS_MCS9 = 0x49, > + > + DESC_RATEVHT4SS_MCS0 = 0x4a, > + DESC_RATEVHT4SS_MCS1 = 0x4b, > + DESC_RATEVHT4SS_MCS2 = 0x4c, > + DESC_RATEVHT4SS_MCS3 = 0x4d, > + DESC_RATEVHT4SS_MCS4 = 0x4e, > + DESC_RATEVHT4SS_MCS5 = 0x4f, > + DESC_RATEVHT4SS_MCS6 = 0x50, > + DESC_RATEVHT4SS_MCS7 = 0x51, > + DESC_RATEVHT4SS_MCS8 = 0x52, > + DESC_RATEVHT4SS_MCS9 = 0x53, > + > + DESC_RATE_MAX, > +}; > + > +enum rtw_regulatory_domains { > + RTW_REGD_FCC = 0, > + RTW_REGD_MKK = 1, > + RTW_REGD_ETSI = 2, > + RTW_REGD_WW = 3, > + > + RTW_REGD_MAX > +}; > + > +enum rtw_flags { > + RTW_FLAG_RUNNING, > + RTW_FLAG_FW_RUNNING, > + RTW_FLAG_SCANNING, > + RTW_FLAG_INACTIVE_PS, > + RTW_FLAG_LEISURE_PS, > + RTW_FLAG_DIG_DISABLE, > + > + NUM_OF_RTW_FLAGS, > +}; > + > +/* the power index is represented by differences, which cck-1s & ht40-1s are > + * the base values, so for 1s's differences, there are only ht20 & ofdm > + */ > +struct rtw_2g_1s_pwr_idx_diff { > +#ifdef __LITTLE_ENDIAN > + s8 ofdm:4; > + s8 bw20:4; > +#else > + s8 bw20:4; > + s8 ofdm:4; > +#endif > +} __packed; > + > +struct rtw_2g_ns_pwr_idx_diff { > +#ifdef __LITTLE_ENDIAN > + s8 bw20:4; > + s8 bw40:4; > + s8 cck:4; > + s8 ofdm:4; > +#else > + s8 ofdm:4; > + s8 cck:4; > + s8 bw40:4; > + s8 bw20:4; > +#endif > +} __packed; > + > +struct rtw_2g_txpwr_idx { > + u8 cck_base[6]; > + u8 bw40_base[5]; > + struct rtw_2g_1s_pwr_idx_diff ht_1s_diff; > + struct rtw_2g_ns_pwr_idx_diff ht_2s_diff; > + struct rtw_2g_ns_pwr_idx_diff ht_3s_diff; > + struct rtw_2g_ns_pwr_idx_diff ht_4s_diff; > +}; > + > +struct rtw_5g_ht_1s_pwr_idx_diff { > +#ifdef __LITTLE_ENDIAN > + s8 ofdm:4; > + s8 bw20:4; > +#else > + s8 bw20:4; > + s8 ofdm:4; > +#endif > +} __packed; > + > +struct rtw_5g_ht_ns_pwr_idx_diff { > +#ifdef __LITTLE_ENDIAN > + s8 bw20:4; > + s8 bw40:4; > +#else > + s8 bw40:4; > + s8 bw20:4; > +#endif > +} __packed; > + > +struct rtw_5g_ofdm_ns_pwr_idx_diff { > +#ifdef __LITTLE_ENDIAN > + s8 ofdm_3s:4; > + s8 ofdm_2s:4; > + s8 ofdm_4s:4; > + s8 res:4; > +#else > + s8 res:4; > + s8 ofdm_4s:4; > + s8 ofdm_2s:4; > + s8 ofdm_3s:4; > +#endif > +} __packed; > + > +struct rtw_5g_vht_ns_pwr_idx_diff { > +#ifdef __LITTLE_ENDIAN > + s8 bw160:4; > + s8 bw80:4; > +#else > + s8 bw80:4; > + s8 bw160:4; > +#endif > +} __packed; > + > +struct rtw_5g_txpwr_idx { > + u8 bw40_base[14]; > + struct rtw_5g_ht_1s_pwr_idx_diff ht_1s_diff; > + struct rtw_5g_ht_ns_pwr_idx_diff ht_2s_diff; > + struct rtw_5g_ht_ns_pwr_idx_diff ht_3s_diff; > + struct rtw_5g_ht_ns_pwr_idx_diff ht_4s_diff; > + struct rtw_5g_ofdm_ns_pwr_idx_diff ofdm_diff; > + struct rtw_5g_vht_ns_pwr_idx_diff vht_1s_diff; > + struct rtw_5g_vht_ns_pwr_idx_diff vht_2s_diff; > + struct rtw_5g_vht_ns_pwr_idx_diff vht_3s_diff; > + struct rtw_5g_vht_ns_pwr_idx_diff vht_4s_diff; > +}; > + > +struct rtw_txpwr_idx { > + struct rtw_2g_txpwr_idx pwr_idx_2g; > + struct rtw_5g_txpwr_idx pwr_idx_5g; > +}; > + > +struct rtw_timer_list { > + struct timer_list timer; > + void (*function)(void *data); > + void *args; > +}; > + > +struct rtw_channel_params { > + u8 center_chan; > + u8 bandwidth; > + u8 primary_chan_idx; > +}; > + > +struct rtw_hw_reg { > + u32 addr; > + u32 mask; > +}; > + > +struct rtw_backup_info { > + u8 len; > + u32 reg; > + u32 val; > +}; > + > +enum rtw_vif_port_set { > + PORT_SET_MAC_ADDR = BIT(0), > + PORT_SET_BSSID = BIT(1), > + PORT_SET_NET_TYPE = BIT(2), > + PORT_SET_AID = BIT(3), > +}; > + > +struct rtw_vif_port { > + struct rtw_hw_reg mac_addr; > + struct rtw_hw_reg bssid; > + struct rtw_hw_reg net_type; > + struct rtw_hw_reg aid; > +}; > + > +struct rtw_tx_pkt_info { > + u32 tx_pkt_size; > + u8 offset; > + u8 pkt_offset; > + u8 mac_id; > + u8 rate_id; > + u8 rate; > + u8 qsel; > + u8 bw; > + u8 sec_type; > + bool ampdu_en; > + u8 ampdu_factor; > + u8 ampdu_density; > + u16 seq; > + bool stbc; > + bool ldpc; > + bool dis_rate_fallback; > + bool bmc; > + bool use_rate; > + bool ls; > + bool fs; > + bool short_gi; > +}; > + > +struct rtw_rx_pkt_stat { > + bool phy_status; > + bool icv_err; > + bool crc_err; > + bool decrypted; > + bool is_c2h; > + > + s32 signal_power; > + u16 pkt_len; > + u8 bw; > + u8 drv_info_sz; > + u8 shift; > + u8 rate; > + u8 mac_id; > + u8 cam_id; > + u8 ppdu_cnt; > + u32 tsf_low; > + s8 rx_power[RTW_RF_PATH_MAX]; > + u8 rssi; > + u8 rxsc; > + struct rtw_sta_info *si; > + struct ieee80211_vif *vif; > +}; > + > +struct rtw_traffic_stats { > + /* units in bytes */ > + u64 tx_unicast; > + u64 rx_unicast; > + > + /* count for packets */ > + u64 tx_cnt; > + u64 rx_cnt; > + > + /* units in Mbps */ > + u32 tx_throughput; > + u32 rx_throughput; > +}; > + > +enum rtw_lps_mode { > + RTW_MODE_ACTIVE = 0, > + RTW_MODE_LPS = 1, > + RTW_MODE_WMM_PS = 2, > +}; > + > +enum rtw_pwr_state { > + RTW_RF_OFF = 0x0, > + RTW_RF_ON = 0x4, > + RTW_ALL_ON = 0xc, > +}; > + > +struct rtw_lps_conf { > + /* the interface to enter lps */ > + struct rtw_vif *rtwvif; > + enum rtw_lps_mode mode; > + enum rtw_pwr_state state; > + u8 awake_interval; > + u8 rlbm; > + u8 smart_ps; > + u8 port_id; > +}; > + > +enum rtw_hw_key_type { > + RTW_CAM_NONE = 0, > + RTW_CAM_WEP40 = 1, > + RTW_CAM_TKIP = 2, > + RTW_CAM_AES = 4, > + RTW_CAM_WEP104 = 5, > +}; > + > +struct rtw_cam_entry { > + bool valid; > + bool group; > + u8 addr[ETH_ALEN]; > + u8 hw_key_type; > + struct ieee80211_key_conf *key; > +}; > + > +struct rtw_sec_desc { > + /* search strategy */ > + bool default_key_search; > + > + u32 total_cam_num; > + struct rtw_cam_entry cam_table[RTW_MAX_SEC_CAM_NUM]; > + DECLARE_BITMAP(cam_map, RTW_MAX_SEC_CAM_NUM); > +}; > + > +#define RTW_BC_MC_MACID 1 > +DECLARE_EWMA(rssi, 10, 16); > + > +struct rtw_sta_info { > + struct ieee80211_sta *sta; > + struct ieee80211_vif *vif; > + > + struct ewma_rssi avg_rssi; > + u8 rssi_level; > + > + u8 mac_id; > + u8 rate_id; > + enum rtw_bandwidth bw_mode; > + enum rtw_rf_type rf_type; > + enum rtw_wireless_set wireless_set; > + u8 stbc_en:2; > + u8 ldpc_en:2; > + bool sgi_enable; > + bool vht_enable; > + bool updated; > + u8 init_ra_lv; > + u64 ra_mask; > +}; > + > +struct rtw_vif { > + struct ieee80211_vif *vif; > + enum rtw_net_type net_type; > + u16 aid; > + u8 mac_addr[ETH_ALEN]; > + u8 bssid[ETH_ALEN]; > + u8 port; > + const struct rtw_vif_port *conf; > + > + struct rtw_traffic_stats stats; > + bool in_lps; > +}; > + > +struct rtw_regulatory { > + char alpha2[2]; > + u8 chplan; > + u8 txpwr_regd; > +}; > + > +struct rtw_chip_ops { > + int (*mac_init)(struct rtw_dev *rtwdev); > + int (*read_efuse)(struct rtw_dev *rtwdev, u8 *map); > + void (*phy_set_param)(struct rtw_dev *rtwdev); > + void (*set_channel)(struct rtw_dev *rtwdev, u8 channel, > + u8 bandwidth, u8 primary_chan_idx); > + void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc, > + struct rtw_rx_pkt_stat *pkt_stat, > + struct ieee80211_rx_status *rx_status); > + u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, > + u32 addr, u32 mask); > + bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, > + u32 addr, u32 mask, u32 data); > + void (*set_tx_power_index)(struct rtw_dev *rtwdev, u8 power_index, > + u8 rf_path, u8 rate); > + int (*rsvd_page_dump)(struct rtw_dev *rtwdev, u8 *buf, u32 offset, > + u32 size); > + void (*set_antenna)(struct rtw_dev *rtwdev, u8 antenna_tx, > + u8 antenna_rx); > + void (*cfg_ldo25)(struct rtw_dev *rtwdev, bool enable); > + void (*false_alarm_statistics)(struct rtw_dev *rtwdev); > + void (*do_iqk)(struct rtw_dev *rtwdev); > +}; > + > +#define RTW_PWR_POLLING_CNT 20000 > + > +#define RTW_PWR_CMD_READ 0x00 > +#define RTW_PWR_CMD_WRITE 0x01 > +#define RTW_PWR_CMD_POLLING 0x02 > +#define RTW_PWR_CMD_DELAY 0x03 > +#define RTW_PWR_CMD_END 0x04 > + > +/* define the base address of each block */ > +#define RTW_PWR_ADDR_MAC 0x00 > +#define RTW_PWR_ADDR_USB 0x01 > +#define RTW_PWR_ADDR_PCIE 0x02 > +#define RTW_PWR_ADDR_SDIO 0x03 > + > +#define RTW_PWR_INTF_SDIO_MSK BIT(0) > +#define RTW_PWR_INTF_USB_MSK BIT(1) > +#define RTW_PWR_INTF_PCI_MSK BIT(2) > +#define RTW_PWR_INTF_ALL_MSK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) > + > +#define RTW_PWR_CUT_A_MSK BIT(1) > +#define RTW_PWR_CUT_B_MSK BIT(2) > +#define RTW_PWR_CUT_C_MSK BIT(3) > +#define RTW_PWR_CUT_D_MSK BIT(4) > +#define RTW_PWR_CUT_E_MSK BIT(5) > +#define RTW_PWR_CUT_F_MSK BIT(6) > +#define RTW_PWR_CUT_G_MSK BIT(7) > +#define RTW_PWR_CUT_ALL_MSK 0xFF > + > +enum rtw_pwr_seq_cmd_delay_unit { > + RTW_PWR_DELAY_US, > + RTW_PWR_DELAY_MS, > +}; > + > +struct rtw_pwr_seq_cmd { > + u16 offset; > + u8 cut_mask; > + u8 intf_mask; > + u8 base:4; > + u8 cmd:4; > + u8 mask; > + u8 value; > +}; > + > +enum rtw_chip_ver { > + RTW_CHIP_VER_CUT_A = 0x00, > + RTW_CHIP_VER_CUT_B = 0x01, > + RTW_CHIP_VER_CUT_C = 0x02, > + RTW_CHIP_VER_CUT_D = 0x03, > + RTW_CHIP_VER_CUT_E = 0x04, > + RTW_CHIP_VER_CUT_F = 0x05, > + RTW_CHIP_VER_CUT_G = 0x06, > +}; > + > +#define RTW_INTF_PHY_PLATFORM_ALL 0 > + > +enum rtw_intf_phy_cut { > + RTW_INTF_PHY_CUT_A = BIT(0), > + RTW_INTF_PHY_CUT_B = BIT(1), > + RTW_INTF_PHY_CUT_C = BIT(2), > + RTW_INTF_PHY_CUT_D = BIT(3), > + RTW_INTF_PHY_CUT_E = BIT(4), > + RTW_INTF_PHY_CUT_F = BIT(5), > + RTW_INTF_PHY_CUT_G = BIT(6), > + RTW_INTF_PHY_CUT_ALL = 0xFFFF, > +}; > + > +enum rtw_ip_sel { > + RTW_IP_SEL_PHY = 0, > + RTW_IP_SEL_MAC = 1, > + RTW_IP_SEL_DBI = 2, > + > + RTW_IP_SEL_UNDEF = 0xFFFF > +}; > + > +enum rtw_pq_map_id { > + RTW_PQ_MAP_VO = 0x0, > + RTW_PQ_MAP_VI = 0x1, > + RTW_PQ_MAP_BE = 0x2, > + RTW_PQ_MAP_BK = 0x3, > + RTW_PQ_MAP_MG = 0x4, > + RTW_PQ_MAP_HI = 0x5, > + RTW_PQ_MAP_NUM = 0x6, > + > + RTW_PQ_MAP_UNDEF, > +}; > + > +enum rtw_dma_mapping { > + RTW_DMA_MAPPING_EXTRA = 0, > + RTW_DMA_MAPPING_LOW = 1, > + RTW_DMA_MAPPING_NORMAL = 2, > + RTW_DMA_MAPPING_HIGH = 3, > + > + RTW_DMA_MAPPING_UNDEF, > +}; > + > +struct rtw_rqpn { > + enum rtw_dma_mapping dma_map_vo; > + enum rtw_dma_mapping dma_map_vi; > + enum rtw_dma_mapping dma_map_be; > + enum rtw_dma_mapping dma_map_bk; > + enum rtw_dma_mapping dma_map_mg; > + enum rtw_dma_mapping dma_map_hi; > +}; > + > +struct rtw_page_table { > + u16 hq_num; > + u16 nq_num; > + u16 lq_num; > + u16 exq_num; > + u16 gapq_num; > +}; > + > +struct rtw_intf_phy_para { > + u16 offset; > + u16 value; > + u16 ip_sel; > + u16 cut_mask; > + u16 platform; > +}; > + > +struct rtw_intf_phy_para_table { > + struct rtw_intf_phy_para *usb2_para; > + struct rtw_intf_phy_para *usb3_para; > + struct rtw_intf_phy_para *gen1_para; > + struct rtw_intf_phy_para *gen2_para; > + u8 n_usb2_para; > + u8 n_usb3_para; > + u8 n_gen1_para; > + u8 n_gen2_para; > +}; > + > +struct rtw_table { > + const void *data; > + const u32 size; > + void (*parse)(struct rtw_dev *rtwdev, const struct rtw_table *tbl); > + void (*do_cfg)(struct rtw_dev *rtwdev, const struct rtw_table *tbl, > + u32 addr, u32 data); > + enum rtw_rf_path rf_path; > +}; > + > +static inline void rtw_load_table(struct rtw_dev *rtwdev, > + const struct rtw_table *tbl) > +{ > + (*tbl->parse)(rtwdev, tbl); > +} > + > +enum rtw_rfe_fem { > + RTW_RFE_IFEM, > + RTW_RFE_EFEM, > + RTW_RFE_IFEM2G_EFEM5G, > + RTW_RFE_NUM, > +}; > + > +struct rtw_rfe_def { > + const struct rtw_table *phy_pg_tbl; > + const struct rtw_table *txpwr_lmt_tbl; > +}; > + > +#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) { \ > + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ > + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ > + } > + > +/* hardware configuration for each IC */ > +struct rtw_chip_info { > + struct rtw_chip_ops *ops; > + u8 id; > + > + const char *fw_name; > + u8 tx_pkt_desc_sz; > + u8 tx_buf_desc_sz; > + u8 rx_pkt_desc_sz; > + u8 rx_buf_desc_sz; > + u32 phy_efuse_size; > + u32 log_efuse_size; > + u32 ptct_efuse_size; > + u32 txff_size; > + u32 rxff_size; > + u8 band; > + u8 page_size; > + u8 csi_buf_pg_num; > + u8 dig_max; > + u8 dig_min; > + > + bool ht_supported; > + bool vht_supported; > + > + /* init values */ > + u8 sys_func_en; > + struct rtw_pwr_seq_cmd **pwr_on_seq; > + struct rtw_pwr_seq_cmd **pwr_off_seq; > + struct rtw_rqpn *rqpn_table; > + struct rtw_page_table *page_table; > + struct rtw_intf_phy_para_table *intf_table; > + > + struct rtw_hw_reg *dig; > + u32 rf_base_addr[2]; > + u32 rf_sipi_addr[2]; > + > + const struct rtw_table *mac_tbl; > + const struct rtw_table *agc_tbl; > + const struct rtw_table *bb_tbl; > + const struct rtw_table *rf_tbl[RTW_RF_PATH_MAX]; > + > + const struct rtw_rfe_def *rfe_defs; > + u32 rfe_defs_size; > +}; > + > +struct rtw_dm_info { > + u32 cck_fa_cnt; > + u32 ofdm_fa_cnt; > + u32 total_fa_cnt; > + u8 min_rssi; > + u8 pre_min_rssi; > + u16 fa_history[4]; > + u8 igi_history[4]; > + u8 igi_bitmap; > + bool damping; > + u8 damping_cnt; > + u8 damping_rssi; > + > + u8 cck_gi_u_bnd; > + u8 cck_gi_l_bnd; > +}; > + > +struct rtw_efuse { > + u32 size; > + u32 physical_size; > + u32 logical_size; > + u32 protect_size; > + > + u8 addr[ETH_ALEN]; > + u8 channel_plan; > + u8 country_code[2]; > + u8 rfe_option; > + u8 thermal_meter; > + u8 crystal_cap; > + u8 ant_div_cfg; > + u8 ant_div_type; > + u8 regd; > + > + u8 lna_type_2g; > + u8 lna_type_5g; > + u8 glna_type; > + u8 alna_type; > + bool ext_lna_2g; > + bool ext_lna_5g; > + u8 pa_type_2g; > + u8 pa_type_5g; > + u8 gpa_type; > + u8 apa_type; > + bool ext_pa_2g; > + bool ext_pa_5g; > + u8 x3d7; > + u8 x3d8; > + > + bool btcoex; > + /* bt share antenna with wifi */ > + bool share_ant; > + u8 bt_setting; > + > + struct { > + u8 hci; > + u8 bw; > + u8 ptcl; > + u8 nss; > + u8 ant_num; > + } hw_cap; > + > + struct rtw_txpwr_idx txpwr_idx_table[4]; > +}; > + > +struct rtw_phy_cond { > +#ifdef __LITTLE_ENDIAN > + u32 rfe:8; > + u32 intf:4; > + u32 pkg:4; > + u32 plat:4; > + u32 intf_rsvd:4; > + u32 cut:4; > + u32 branch:2; > + u32 neg:1; > + u32 pos:1; > +#else > + u32 pos:1; > + u32 neg:1; > + u32 branch:2; > + u32 cut:4; > + u32 intf_rsvd:4; > + u32 plat:4; > + u32 pkg:4; > + u32 intf:4; > + u32 rfe:8; > +#endif > + /* for intf:4 */ > + #define INTF_PCIE BIT(0) > + #define INTF_USB BIT(1) > + #define INTF_SDIO BIT(2) > + /* for branch:2 */ > + #define BRANCH_IF 0 > + #define BRANCH_ELIF 1 > + #define BRANCH_ELSE 2 > + #define BRANCH_ENDIF 3 > +}; > + > +struct rtw_fifo_conf { > + /* tx fifo information */ > + u16 rsvd_boundary; > + u16 rsvd_pg_num; > + u16 rsvd_drv_pg_num; > + u16 txff_pg_num; > + u16 acq_pg_num; > + u16 rsvd_drv_addr; > + u16 rsvd_h2c_info_addr; > + u16 rsvd_h2c_sta_info_addr; > + u16 rsvd_h2cq_addr; > + u16 rsvd_cpu_instr_addr; > + u16 rsvd_fw_txbuf_addr; > + u16 rsvd_csibuf_addr; > + enum rtw_dma_mapping pq_map[RTW_PQ_MAP_NUM]; > +}; > + > +struct rtw_fw_state { > + const struct firmware *firmware; > + struct completion completion; > + u16 version; > + u8 sub_version; > + u8 sub_index; > + u16 h2c_version; > +}; > + > +struct rtw_hal { > + u32 rcr; > + > + u32 chip_version; > + u8 fab_version; > + u8 cut_version; > + u8 mp_chip; > + u8 oem_id; > + struct rtw_phy_cond phy_cond; > + > + u8 ps_mode; > + u8 current_channel; > + u8 current_band_width; > + u8 current_band_type; > + u8 sec_ch_offset; > + u8 rf_type; > + u8 rf_path_num; > + u8 antenna_tx; > + u8 antenna_rx; > + > + /* protect tx power section */ > + struct mutex tx_power_mutex; > + s8 tx_pwr_by_rate_offset_2g[RTW_RF_PATH_MAX] > + [DESC_RATE_MAX]; > + s8 tx_pwr_by_rate_offset_5g[RTW_RF_PATH_MAX] > + [DESC_RATE_MAX]; > + s8 tx_pwr_by_rate_base_2g[RTW_RF_PATH_MAX] > + [RTW_RATE_SECTION_MAX]; > + s8 tx_pwr_by_rate_base_5g[RTW_RF_PATH_MAX] > + [RTW_RATE_SECTION_MAX]; > + s8 tx_pwr_limit_2g[RTW_REGD_MAX] > + [RTW_CHANNEL_WIDTH_MAX] > + [RTW_RATE_SECTION_MAX] > + [RTW_MAX_CHANNEL_NUM_2G]; > + s8 tx_pwr_limit_5g[RTW_REGD_MAX] > + [RTW_CHANNEL_WIDTH_MAX] > + [RTW_RATE_SECTION_MAX] > + [RTW_MAX_CHANNEL_NUM_5G]; > +}; > + > +struct rtw_dev { > + struct ieee80211_hw *hw; > + struct device *dev; > + > + struct rtw_hci hci; > + > + struct rtw_chip_info *chip; > + struct rtw_hal hal; > + struct rtw_fifo_conf fifo; > + struct rtw_fw_state fw; > + struct rtw_efuse efuse; > + struct rtw_sec_desc sec; > + struct rtw_traffic_stats stats; > + struct rtw_regulatory regd; > + > + struct rtw_dm_info dm_info; > + > + /* ensures exclusive access from mac80211 callbacks */ > + struct mutex mutex; > + > + /* lock for dm to use */ > + spinlock_t dm_lock; > + > + /* read/write rf register */ > + spinlock_t rf_lock; > + > + /* watch dog every 2 sec */ > + struct delayed_work watch_dog_work; > + u32 watch_dog_cnt; > + > + struct list_head rsvd_page_list; > + > + /* c2h cmd queue & handler work */ > + struct sk_buff_head c2h_queue; > + struct work_struct c2h_work; > + > + struct { > + /* incicate the mail box to use with fw */ > + u8 last_box_num; > + /* protect to send h2c to fw */ > + spinlock_t lock; > + u32 seq; > + } h2c; > + > + /* lps power state & handler work */ > + struct rtw_lps_conf lps_conf; > + struct delayed_work lps_work; > + > + struct dentry *debugfs; > + > + u8 sta_cnt; > + > + DECLARE_BITMAP(mac_id_map, RTW_MAX_MAC_ID_NUM); > + DECLARE_BITMAP(flags, NUM_OF_RTW_FLAGS); > + > + u8 mp_mode; > + > + /* hci related data, must be last */ > + u8 priv[0] __aligned(sizeof(void *)); > +}; > + > +#include "hci.h" > + > +static inline bool rtw_flag_check(struct rtw_dev *rtwdev, enum rtw_flags flag) > +{ > + return test_bit(flag, rtwdev->flags); > +} > + > +static inline void rtw_flag_clear(struct rtw_dev *rtwdev, enum rtw_flags flag) > +{ > + clear_bit(flag, rtwdev->flags); > +} > + > +static inline void rtw_flag_set(struct rtw_dev *rtwdev, enum rtw_flags flag) > +{ > + set_bit(flag, rtwdev->flags); > +} > + > +static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr) > +{ > + __le16 fc = hdr->frame_control; > + u8 *bssid; > + > + if (ieee80211_has_tods(fc)) > + bssid = hdr->addr1; > + else if (ieee80211_has_fromds(fc)) > + bssid = hdr->addr2; > + else > + bssid = hdr->addr3; > + > + return bssid; > +} > + > +static inline bool check_hw_ready(struct rtw_dev *rtwdev, > + u32 addr, u32 mask, u32 target) > +{ > + u32 cnt; > + > + for (cnt = 0; cnt < 1000; cnt++) { > + if (rtw_read32_mask(rtwdev, addr, mask) == target) > + return true; > + > + udelay(10); > + } > + > + return false; > +} > + > +#define rtw_iterate_vifs(rtwdev, iterator, data) > \ > + ieee80211_iterate_active_interfaces(rtwdev->hw, > \ > + IEEE80211_IFACE_ITER_NORMAL, iterator, data) > +#define rtw_iterate_vifs_atomic(rtwdev, iterator, data) > \ > + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, > \ > + IEEE80211_IFACE_ITER_NORMAL, iterator, data) > +#define rtw_iterate_stas_atomic(rtwdev, iterator, data) > \ > + ieee80211_iterate_stations_atomic(rtwdev->hw, iterator, data) > + > +void rtw_get_channel_params(struct cfg80211_chan_def *chandef, > + struct rtw_channel_params *ch_param); > +void rtw_set_channel(struct rtw_dev *rtwdev); > +void rtw_vif_port_config(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif, > + u32 config); > +void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si); > +int rtw_core_start(struct rtw_dev *rtwdev); > +void rtw_core_stop(struct rtw_dev *rtwdev); > +int rtw_chip_info_setup(struct rtw_dev *rtwdev); > +int rtw_core_init(struct rtw_dev *rtwdev); > +void rtw_core_deinit(struct rtw_dev *rtwdev); > +int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw); > +void rtw_unregister_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw); > + > +#endif > diff --git a/drivers/net/wireless/realtek/rtw88/reg.h > b/drivers/net/wireless/realtek/rtw88/reg.h > new file mode 100644 > index 0000000..6e81829 > --- /dev/null > +++ b/drivers/net/wireless/realtek/rtw88/reg.h > @@ -0,0 +1,411 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* Copyright(c) 2018 Realtek Corporation. > + */ > + > +#ifndef __RTW_REG_DEF_H__ > +#define __RTW_REG_DEF_H__ > + > +#define REG_SYS_FUNC_EN 0x0002 > +#define BIT_FEN_CPUEN BIT(2) > +#define BIT_FEN_BB_GLB_RST BIT(1) > +#define BIT_FEN_BB_RSTB BIT(0) > +#define REG_SYS_PW_CTRL 0x0004 > +#define REG_SYS_CLK_CTRL 0x0008 > +#define BIT_CPU_CLK_EN BIT(14) > + > +#define REG_RSV_CTRL 0x001C > +#define BIT_WLMCU_IOIF BIT(0) > +#define REG_RF_CTRL 0x001F > +#define BIT_RF_SDM_RSTB BIT(2) > +#define BIT_RF_RSTB BIT(1) > +#define BIT_RF_EN BIT(0) > + > +#define REG_AFE_CTRL1 0x0024 > +#define BIT_MAC_CLK_SEL (BIT(20) | BIT(21)) > +#define REG_EFUSE_CTRL 0x0030 > +#define BIT_EF_FLAG BIT(31) > +#define BIT_SHIFT_EF_ADDR 8 > +#define BIT_MASK_EF_ADDR 0x3ff > +#define BIT_MASK_EF_DATA 0xff > +#define BITS_EF_ADDR (BIT_MASK_EF_ADDR << BIT_SHIFT_EF_ADDR) > + > +#define REG_LDO_EFUSE_CTRL 0x0034 > +#define BIT_MASK_EFUSE_BANK_SEL (BIT(8) | BIT(9)) > + > +#define REG_GPIO_MUXCFG 0x0040 > +#define BIT_FSPI_EN BIT(19) > +#define BIT_WLRFE_4_5_EN BIT(2) > + > +#define REG_LED_CFG 0x004C > +#define BIT_LNAON_SEL_EN BIT(26) > +#define BIT_PAPE_SEL_EN BIT(25) > +#define REG_PAD_CTRL1 0x0064 > +#define BIT_PAPE_WLBT_SEL BIT(29) > +#define BIT_LNAON_WLBT_SEL BIT(28) > +#define REG_WL_BT_PWR_CTRL 0x0068 > +#define BIT_BT_FUNC_EN BIT(18) > +#define BIT_BT_DIG_CLK_EN BIT(8) > +#define REG_HCI_OPT_CTRL 0x0074 > + > +#define REG_MCUFW_CTRL 0x0080 > +#define BIT_ANA_PORT_EN BIT(22) > +#define BIT_MAC_PORT_EN BIT(21) > +#define BIT_BOOT_FSPI_EN BIT(20) > +#define BIT_FW_INIT_RDY BIT(15) > +#define BIT_FW_DW_RDY BIT(14) > +#define BIT_RPWM_TOGGLE BIT(7) > +#define BIT_DMEM_CHKSUM_OK BIT(6) > +#define BIT_DMEM_DW_OK BIT(5) > +#define BIT_IMEM_CHKSUM_OK BIT(4) > +#define BIT_IMEM_DW_OK BIT(3) > +#define BIT_IMEM_BOOT_LOAD_CHECKSUM_OK BIT(2) > +#define BIT_MCUFWDL_EN BIT(0) > +#define BIT_CHECK_SUM_OK (BIT(4) | BIT(6)) > +#define FW_READY (BIT_FW_INIT_RDY | BIT_FW_DW_RDY | > \ > + BIT_IMEM_DW_OK | BIT_DMEM_DW_OK | > \ > + BIT_CHECK_SUM_OK) > +#define FW_READY_MASK 0xffff > + > +#define REG_SYS_CFG1 0x00F0 > +#define BIT_RTL_ID BIT(23) > +#define BIT_RF_TYPE_ID BIT(27) > +#define BIT_SHIFT_VENDOR_ID 16 > +#define BIT_MASK_VENDOR_ID 0xf > +#define BIT_VENDOR_ID(x) (((x) & BIT_MASK_VENDOR_ID) << > BIT_SHIFT_VENDOR_ID) > +#define BITS_VENDOR_ID (BIT_MASK_VENDOR_ID << > BIT_SHIFT_VENDOR_ID) > +#define BIT_CLEAR_VENDOR_ID(x) ((x) & (~BITS_VENDOR_ID)) > +#define BIT_GET_VENDOR_ID(x) (((x) >> BIT_SHIFT_VENDOR_ID) & > BIT_MASK_VENDOR_ID) > +#define BIT_SHIFT_CHIP_VER 12 > +#define BIT_MASK_CHIP_VER 0xf > +#define BIT_CHIP_VER(x) (((x) & BIT_MASK_CHIP_VER) << > BIT_SHIFT_CHIP_VER) > +#define BITS_CHIP_VER (BIT_MASK_CHIP_VER << > BIT_SHIFT_CHIP_VER) > +#define BIT_CLEAR_CHIP_VER(x) ((x) & (~BITS_CHIP_VER)) > +#define BIT_GET_CHIP_VER(x) (((x) >> BIT_SHIFT_CHIP_VER) & > BIT_MASK_CHIP_VER) > +#define REG_SYS_STATUS1 0x00F4 > +#define REG_SYS_STATUS2 0x00F8 > +#define REG_SYS_CFG2 0x00FC > +#define REG_WLRF1 0x00EC > +#define BIT_WLRF1_BBRF_EN (BIT(24) | BIT(25) | BIT(26)) > +#define REG_CR 0x0100 > +#define BIT_32K_CAL_TMR_EN BIT(10) > +#define BIT_MAC_SEC_EN BIT(9) > +#define BIT_ENSWBCN BIT(8) > +#define BIT_MACRXEN BIT(7) > +#define BIT_MACTXEN BIT(6) > +#define BIT_SCHEDULE_EN BIT(5) > +#define BIT_PROTOCOL_EN BIT(4) > +#define BIT_RXDMA_EN BIT(3) > +#define BIT_TXDMA_EN BIT(2) > +#define BIT_HCI_RXDMA_EN BIT(1) > +#define BIT_HCI_TXDMA_EN BIT(0) > +#define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | > BIT_TXDMA_EN | \ > + BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \ > + BIT_MACTXEN | BIT_MACRXEN) > +#define BIT_SHIFT_TXDMA_VOQ_MAP 4 > +#define BIT_MASK_TXDMA_VOQ_MAP 0x3 > +#define BIT_TXDMA_VOQ_MAP(x) > \ > + (((x) & BIT_MASK_TXDMA_VOQ_MAP) << BIT_SHIFT_TXDMA_VOQ_MAP) > +#define BIT_SHIFT_TXDMA_VIQ_MAP 6 > +#define BIT_MASK_TXDMA_VIQ_MAP 0x3 > +#define BIT_TXDMA_VIQ_MAP(x) > \ > + (((x) & BIT_MASK_TXDMA_VIQ_MAP) << BIT_SHIFT_TXDMA_VIQ_MAP) > +#define REG_TXDMA_PQ_MAP 0x010C > +#define BIT_SHIFT_TXDMA_BEQ_MAP 8 > +#define BIT_MASK_TXDMA_BEQ_MAP 0x3 > +#define BIT_TXDMA_BEQ_MAP(x) > \ > + (((x) & BIT_MASK_TXDMA_BEQ_MAP) << BIT_SHIFT_TXDMA_BEQ_MAP) > +#define BIT_SHIFT_TXDMA_BKQ_MAP 10 > +#define BIT_MASK_TXDMA_BKQ_MAP 0x3 > +#define BIT_TXDMA_BKQ_MAP(x) > \ > + (((x) & BIT_MASK_TXDMA_BKQ_MAP) << BIT_SHIFT_TXDMA_BKQ_MAP) > +#define BIT_SHIFT_TXDMA_MGQ_MAP 12 > +#define BIT_MASK_TXDMA_MGQ_MAP 0x3 > +#define BIT_TXDMA_MGQ_MAP(x) > \ > + (((x) & BIT_MASK_TXDMA_MGQ_MAP) << > BIT_SHIFT_TXDMA_MGQ_MAP) > +#define BIT_SHIFT_TXDMA_HIQ_MAP 14 > +#define BIT_MASK_TXDMA_HIQ_MAP 0x3 > +#define BIT_TXDMA_HIQ_MAP(x) > \ > + (((x) & BIT_MASK_TXDMA_HIQ_MAP) << BIT_SHIFT_TXDMA_HIQ_MAP) > +#define BIT_SHIFT_TXSC_40M 4 > +#define BIT_MASK_TXSC_40M 0xf > +#define BIT_TXSC_40M(x) \ > + (((x) & BIT_MASK_TXSC_40M) << BIT_SHIFT_TXSC_40M) > +#define BIT_SHIFT_TXSC_20M 0 > +#define BIT_MASK_TXSC_20M 0xf > +#define BIT_TXSC_20M(x) \ > + (((x) & BIT_MASK_TXSC_20M) << BIT_SHIFT_TXSC_20M) > +#define BIT_SHIFT_MAC_CLK_SEL 20 > +#define MAC_CLK_HW_DEF_80M 0 > +#define MAC_CLK_HW_DEF_40M 1 > +#define MAC_CLK_HW_DEF_20M 2 > +#define MAC_CLK_SPEED 80 > + > +#define REG_CR 0x0100 > +#define REG_TRXFF_BNDY 0x0114 > +#define REG_RXFF_BNDY 0x011C > +#define REG_PKTBUF_DBG_CTRL 0x0140 > +#define REG_C2HEVT 0x01A0 > +#define REG_HMETFR 0x01CC > +#define REG_HMEBOX0 0x01D0 > +#define REG_HMEBOX1 0x01D4 > +#define REG_HMEBOX2 0x01D8 > +#define REG_HMEBOX3 0x01DC > +#define REG_HMEBOX0_EX 0x01F0 > +#define REG_HMEBOX1_EX 0x01F4 > +#define REG_HMEBOX2_EX 0x01F8 > +#define REG_HMEBOX3_EX 0x01FC > + > +#define REG_FIFOPAGE_CTRL_2 0x0204 > +#define BIT_BCN_VALID_V1 BIT(15) > +#define BIT_MASK_BCN_HEAD_1_V1 0xfff > +#define REG_AUTO_LLT_V1 0x0208 > +#define BIT_AUTO_INIT_LLT_V1 BIT(0) > +#define REG_TXDMA_OFFSET_CHK 0x020C > +#define REG_TXDMA_STATUS 0x0210 > +#define BTI_PAGE_OVF BIT(2) > +#define REG_RQPN_CTRL_1 0x0228 > +#define REG_RQPN_CTRL_2 0x022C > +#define BIT_LD_RQPN BIT(31) > +#define REG_FIFOPAGE_INFO_1 0x0230 > +#define REG_FIFOPAGE_INFO_2 0x0234 > +#define REG_FIFOPAGE_INFO_3 0x0238 > +#define REG_FIFOPAGE_INFO_4 0x023C > +#define REG_FIFOPAGE_INFO_5 0x0240 > +#define REG_H2C_HEAD 0x0244 > +#define REG_H2C_TAIL 0x0248 > +#define REG_H2C_READ_ADDR 0x024C > +#define REG_H2C_INFO 0x0254 > + > +#define REG_FWHW_TXQ_CTRL 0x0420 > +#define BIT_EN_WR_FREE_TAIL BIT(20) > +#define REG_BCNQ_BDNY_V1 0x0424 > +#define REG_LIFETIME_EN 0x0426 > +#define BIT_BA_PARSER_EN BIT(5) > +#define REG_SPEC_SIFS 0x0428 > +#define REG_DARFRC 0x0430 > +#define REG_DARFRCH 0x0434 > +#define REG_RARFRCH 0x043C > +#define REG_ARFR0 0x0444 > +#define REG_ARFRH0 0x0448 > +#define REG_ARFR1_V1 0x044C > +#define REG_ARFRH1_V1 0x0450 > +#define REG_CCK_CHECK 0x0454 > +#define BIT_CHECK_CCK_EN BIT(7) > +#define REG_AMPDU_MAX_TIME_V1 0x0455 > +#define REG_BCNQ1_BDNY_V1 0x0456 > +#define REG_TX_HANG_CTRL 0x045E > +#define BIT_EN_EOF_V1 BIT(2) > +#define REG_DATA_SC 0x0483 > +#define REG_ARFR4 0x049C > +#define REG_ARFRH4 0x04A0 > +#define REG_ARFR5 0x04A4 > +#define REG_ARFRH5 0x04A8 > +#define REG_SW_AMPDU_BURST_MODE_CTRL 0x04BC > +#define BIT_PRE_TX_CMD BIT(6) > +#define REG_PROT_MODE_CTRL 0x04C8 > +#define REG_BAR_MODE_CTRL 0x04CC > +#define REG_PRECNT_CTRL 0x04E5 > +#define BIT_EN_PRECNT BIT(11) > + > +#define REG_EDCA_VO_PARAM 0x0500 > +#define REG_EDCA_VI_PARAM 0x0504 > +#define REG_EDCA_BE_PARAM 0x0508 > +#define REG_EDCA_BK_PARAM 0x050C > +#define REG_PIFS 0x0512 > +#define REG_SIFS 0x0514 > +#define BIT_SHIFT_SIFS_OFDM_CTX 8 > +#define BIT_SHIFT_SIFS_CCK_TRX 16 > +#define BIT_SHIFT_SIFS_OFDM_TRX 24 > +#define REG_SLOT 0x051B > +#define REG_TX_PTCL_CTRL 0x0520 > +#define BIT_SIFS_BK_EN BIT(12) > +#define REG_TXPAUSE 0x0522 > +#define REG_RD_CTRL 0x0524 > +#define BIT_DIS_TXOP_CFE BIT(10) > +#define BIT_DIS_LSIG_CFE BIT(9) > +#define BIT_DIS_STBC_CFE BIT(8) > +#define REG_TBTT_PROHIBIT 0x0540 > +#define BIT_SHIFT_TBTT_HOLD_TIME_AP 8 > +#define REG_RD_NAV_NXT 0x0544 > +#define REG_BCN_CTRL 0x0550 > +#define BIT_DIS_TSF_UDT BIT(4) > +#define BIT_EN_BCN_FUNCTION BIT(3) > +#define REG_BCN_CTRL_CLINT0 0x0551 > +#define REG_DRVERLYINT 0x0558 > +#define REG_BCNDMATIM 0x0559 > +#define REG_USTIME_TSF 0x055C > +#define REG_BCN_MAX_ERR 0x055D > +#define REG_RXTSF_OFFSET_CCK 0x055E > +#define REG_MISC_CTRL 0x0577 > +#define BIT_EN_FREE_CNT BIT(3) > +#define BIT_DIS_SECOND_CCA (BIT(0) | BIT(1)) > +#define REG_TIMER0_SRC_SEL 0x05B4 > +#define BIT_TSFT_SEL_TIMER0 (BIT(4) | BIT(5) | BIT(6)) > + > +#define REG_TCR 0x0604 > +#define REG_RCR 0x0608 > +#define BIT_APP_FCS BIT(31) > +#define BIT_APP_MIC BIT(30) > +#define BIT_APP_ICV BIT(29) > +#define BIT_APP_PHYSTS BIT(28) > +#define BIT_APP_BASSN BIT(27) > +#define BIT_VHT_DACK BIT(26) > +#define BIT_TCPOFLD_EN BIT(25) > +#define BIT_ENMBID BIT(24) > +#define BIT_LSIGEN BIT(23) > +#define BIT_MFBEN BIT(22) > +#define BIT_DISCHKPPDLLEN BIT(21) > +#define BIT_PKTCTL_DLEN BIT(20) > +#define BIT_TIM_PARSER_EN BIT(18) > +#define BIT_BC_MD_EN BIT(17) > +#define BIT_UC_MD_EN BIT(16) > +#define BIT_RXSK_PERPKT BIT(15) > +#define BIT_HTC_LOC_CTRL BIT(14) > +#define BIT_RPFM_CAM_ENABLE BIT(12) > +#define BIT_TA_BCN BIT(11) > +#define BIT_DISDECMYPKT BIT(10) > +#define BIT_AICV BIT(9) > +#define BIT_ACRC32 BIT(8) > +#define BIT_CBSSID_BCN BIT(7) > +#define BIT_CBSSID_DATA BIT(6) > +#define BIT_APWRMGT BIT(5) > +#define BIT_ADD3 BIT(4) > +#define BIT_AB BIT(3) > +#define BIT_AM BIT(2) > +#define BIT_APM BIT(1) > +#define BIT_AAP BIT(0) > +#define REG_RX_PKT_LIMIT 0x060C > +#define REG_RX_DRVINFO_SZ 0x060F > +#define BIT_APP_PHYSTS BIT(28) > +#define REG_USTIME_EDCA 0x0638 > +#define REG_RESP_SIFS_CCK 0x063C > +#define REG_RESP_SIFS_OFDM 0x063E > +#define REG_ACKTO 0x0640 > +#define REG_EIFS 0x0642 > +#define REG_NAV_CTRL 0x0650 > +#define REG_WMAC_TRXPTCL_CTL 0x0668 > +#define BIT_RFMOD (BIT(7) | BIT(8)) > +#define BIT_RFMOD_80M BIT(7) > +#define BIT_RFMOD_40M BIT(8) > +#define REG_WMAC_TRXPTCL_CTL_H 0x066C > +#define REG_RXFLTMAP0 0x06A0 > +#define REG_RXFLTMAP1 0x06A2 > +#define REG_RXFLTMAP2 0x06A4 > +#define REG_BBPSF_CTRL 0x06DC > + > +#define REG_WMAC_OPTION_FUNCTION 0x07D0 > +#define REG_WMAC_OPTION_FUNCTION_1 0x07D4 > + > +#define REG_CPU_DMEM_CON 0x1080 > +#define BIT_WL_PLATFORM_RST BIT(16) > +#define BIT_WL_SECURITY_CLK BIT(15) > +#define BIT_DDMA_EN BIT(8) > + > +#define REG_H2C_PKT_READADDR 0x10D0 > +#define REG_H2C_PKT_WRITEADDR 0x10D4 > +#define REG_FW_DBG7 0x10FC > +#define FW_KEY_MASK 0xffffff00 > + > +#define REG_CR_EXT 0x1100 > + > +#define REG_DDMA_CH0SA 0x1200 > +#define REG_DDMA_CH0DA 0x1204 > +#define REG_DDMA_CH0CTRL 0x1208 > +#define BIT_DDMACH0_OWN BIT(31) > +#define BIT_DDMACH0_CHKSUM_EN BIT(29) > +#define BIT_DDMACH0_CHKSUM_STS BIT(27) > +#define BIT_DDMACH0_RESET_CHKSUM_STS BIT(25) > +#define BIT_DDMACH0_CHKSUM_CONT BIT(24) > +#define BIT_MASK_DDMACH0_DLEN 0x3ffff > + > +#define REG_H2CQ_CSR 0x1330 > +#define BIT_H2CQ_FULL BIT(31) > +#define REG_FAST_EDCA_VOVI_SETTING 0x1448 > +#define REG_FAST_EDCA_BEBK_SETTING 0x144C > + > +#define REG_RXPSF_CTRL 0x1610 > +#define BIT_RXGCK_FIFOTHR_EN BIT(28) > + > +#define BIT_SHIFT_RXGCK_VHT_FIFOTHR 26 > +#define BIT_MASK_RXGCK_VHT_FIFOTHR 0x3 > +#define BIT_RXGCK_VHT_FIFOTHR(x) > \ > + (((x) & BIT_MASK_RXGCK_VHT_FIFOTHR) << > BIT_SHIFT_RXGCK_VHT_FIFOTHR) > +#define BITS_RXGCK_VHT_FIFOTHR > \ > + (BIT_MASK_RXGCK_VHT_FIFOTHR << BIT_SHIFT_RXGCK_VHT_FIFOTHR) > + > +#define BIT_SHIFT_RXGCK_HT_FIFOTHR 24 > +#define BIT_MASK_RXGCK_HT_FIFOTHR 0x3 > +#define BIT_RXGCK_HT_FIFOTHR(x) > \ > + (((x) & BIT_MASK_RXGCK_HT_FIFOTHR) << > BIT_SHIFT_RXGCK_HT_FIFOTHR) > +#define BITS_RXGCK_HT_FIFOTHR > \ > + (BIT_MASK_RXGCK_HT_FIFOTHR << BIT_SHIFT_RXGCK_HT_FIFOTHR) > + > +#define BIT_SHIFT_RXGCK_OFDM_FIFOTHR 22 > +#define BIT_MASK_RXGCK_OFDM_FIFOTHR 0x3 > +#define BIT_RXGCK_OFDM_FIFOTHR(x) > \ > + (((x) & BIT_MASK_RXGCK_OFDM_FIFOTHR) << > BIT_SHIFT_RXGCK_OFDM_FIFOTHR) > +#define BITS_RXGCK_OFDM_FIFOTHR > \ > + (BIT_MASK_RXGCK_OFDM_FIFOTHR << > BIT_SHIFT_RXGCK_OFDM_FIFOTHR) > + > +#define BIT_SHIFT_RXGCK_CCK_FIFOTHR 20 > +#define BIT_MASK_RXGCK_CCK_FIFOTHR 0x3 > +#define BIT_RXGCK_CCK_FIFOTHR(x) > \ > + (((x) & BIT_MASK_RXGCK_CCK_FIFOTHR) << > BIT_SHIFT_RXGCK_CCK_FIFOTHR) > +#define BITS_RXGCK_CCK_FIFOTHR > \ > + (BIT_MASK_RXGCK_CCK_FIFOTHR << BIT_SHIFT_RXGCK_CCK_FIFOTHR) > + > +#define BIT_RXGCK_OFDMCCA_EN BIT(16) > + > +#define BIT_SHIFT_RXPSF_PKTLENTHR 13 > +#define BIT_MASK_RXPSF_PKTLENTHR 0x7 > +#define BIT_RXPSF_PKTLENTHR(x) > \ > + (((x) & BIT_MASK_RXPSF_PKTLENTHR) << BIT_SHIFT_RXPSF_PKTLENTHR) > +#define BITS_RXPSF_PKTLENTHR > \ > + (BIT_MASK_RXPSF_PKTLENTHR << BIT_SHIFT_RXPSF_PKTLENTHR) > +#define BIT_CLEAR_RXPSF_PKTLENTHR(x) ((x) & (~BITS_RXPSF_PKTLENTHR)) > +#define BIT_SET_RXPSF_PKTLENTHR(x, v) > \ > + (BIT_CLEAR_RXPSF_PKTLENTHR(x) | BIT_RXPSF_PKTLENTHR(v)) > + > +#define BIT_RXPSF_CTRLEN BIT(12) > +#define BIT_RXPSF_VHTCHKEN BIT(11) > +#define BIT_RXPSF_HTCHKEN BIT(10) > +#define BIT_RXPSF_OFDMCHKEN BIT(9) > +#define BIT_RXPSF_CCKCHKEN BIT(8) > +#define BIT_RXPSF_OFDMRST BIT(7) > +#define BIT_RXPSF_CCKRST BIT(6) > +#define BIT_RXPSF_MHCHKEN BIT(5) > +#define BIT_RXPSF_CONT_ERRCHKEN BIT(4) > +#define BIT_RXPSF_ALL_ERRCHKEN BIT(3) > + > +#define BIT_SHIFT_RXPSF_ERRTHR 0 > +#define BIT_MASK_RXPSF_ERRTHR 0x7 > +#define BIT_RXPSF_ERRTHR(x) > \ > + (((x) & BIT_MASK_RXPSF_ERRTHR) << BIT_SHIFT_RXPSF_ERRTHR) > +#define BITS_RXPSF_ERRTHR (BIT_MASK_RXPSF_ERRTHR << > BIT_SHIFT_RXPSF_ERRTHR) > +#define BIT_CLEAR_RXPSF_ERRTHR(x) ((x) & (~BITS_RXPSF_ERRTHR)) > +#define BIT_GET_RXPSF_ERRTHR(x) > \ > + (((x) >> BIT_SHIFT_RXPSF_ERRTHR) & BIT_MASK_RXPSF_ERRTHR) > +#define BIT_SET_RXPSF_ERRTHR(x, v) > \ > + (BIT_CLEAR_RXPSF_ERRTHR(x) | BIT_RXPSF_ERRTHR(v)) > + > +#define REG_RXPSF_TYPE_CTRL 0x1614 > + > +#define REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1 0x1700 > +#define REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1 0x1704 > +#define REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1 0x1708 > +#define LTECOEX_READY BIT(29) > +#define LTECOEX_ACCESS_CTRL > REG_WL2LTECOEX_INDIRECT_ACCESS_CTRL_V1 > +#define LTECOEX_WRITE_DATA > REG_WL2LTECOEX_INDIRECT_ACCESS_WRITE_DATA_V1 > +#define LTECOEX_READ_DATA > REG_WL2LTECOEX_INDIRECT_ACCESS_READ_DATA_V1 > + > +#define RF_DTXLOK 0x08 > +#define RF_CFGCH 0x18 > +#define RF_LUTWA 0x33 > +#define RF_LUTWD1 0x3e > +#define RF_LUTWD0 0x3f > +#define RF_XTALX2 0xb8 > +#define RF_MALSEL 0xbe > +#define RF_LUTDBG 0xdf > +#define RF_LUTWE 0xef > + > +#endif > -- > 2.7.4 > > > ------Please consider the environment before printing this e-mail.