Commit a427aca0 authored by Kalle Valo's avatar Kalle Valo

Merge tag 'mt76-for-kvalo-2021-10-23' of https://github.com/nbd168/wireless

mt76 patches for 5.16

* fix a compile error with !CONFIG_PM
* cleanups
* MT7915 DBDC fixes
* endian warning fixes
parents d3c6daa1 52a99a13
......@@ -65,8 +65,11 @@ int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int offset, int len)
offset = be32_to_cpup(list);
ret = mtd_read(mtd, offset, len, &retlen, eep);
put_mtd_device(mtd);
if (ret)
if (ret) {
dev_err(dev->dev, "reading EEPROM from mtd %s failed: %i\n",
part, ret);
goto out_put_node;
}
if (retlen < len) {
ret = -EINVAL;
......
......@@ -1698,6 +1698,19 @@ int mt7615_mcu_fw_log_2_host(struct mt7615_dev *dev, u8 ctrl)
sizeof(data), true);
}
static int mt7615_mcu_cal_cache_apply(struct mt7615_dev *dev)
{
struct {
bool cache_enable;
u8 pad[3];
} data = {
.cache_enable = true
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_CAL_CACHE, &data,
sizeof(data), false);
}
static int mt7663_load_n9(struct mt7615_dev *dev, const char *name)
{
u32 offset = 0, override_addr = 0, flag = FW_START_DLYCAL;
......@@ -1906,9 +1919,14 @@ int mt7615_mcu_init(struct mt7615_dev *dev)
mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
dev_dbg(dev->mt76.dev, "Firmware init done\n");
set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
mt7615_mcu_fw_log_2_host(dev, 0);
return 0;
if (dev->dbdc_support) {
ret = mt7615_mcu_cal_cache_apply(dev);
if (ret)
return ret;
}
return mt7615_mcu_fw_log_2_host(dev, 0);
}
EXPORT_SYMBOL_GPL(mt7615_mcu_init);
......
......@@ -2477,6 +2477,7 @@ void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
#endif /* CONFIG_PM */
u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset)
{
......@@ -2505,7 +2506,6 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val)
mt76_mcu_send_msg(dev, MCU_CMD_REG_WRITE, &req, sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr);
#endif /* CONFIG_PM */
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
MODULE_LICENSE("Dual BSD/GPL");
......@@ -531,6 +531,7 @@ enum {
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
MCU_EXT_CMD_RXDCOC_CAL = 0x59,
MCU_EXT_CMD_TXDPD_CAL = 0x60,
MCU_EXT_CMD_CAL_CACHE = 0x67,
MCU_EXT_CMD_SET_RDD_TH = 0x7c,
MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
};
......
......@@ -82,7 +82,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL,
mt7915_radar_trigger, "%lld\n");
static int
mt7915_fw_debug_set(void *data, u64 val)
mt7915_fw_debug_wm_set(void *data, u64 val)
{
struct mt7915_dev *dev = data;
enum {
......@@ -92,29 +92,103 @@ mt7915_fw_debug_set(void *data, u64 val)
DEBUG_SPL,
DEBUG_RPT_RX,
} debug;
int ret;
dev->fw_debug = !!val;
dev->fw_debug_wm = val ? MCU_FW_LOG_TO_HOST : 0;
mt7915_mcu_fw_log_2_host(dev, dev->fw_debug ? 2 : 0);
ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, dev->fw_debug_wm);
if (ret)
return ret;
for (debug = DEBUG_TXCMD; debug <= DEBUG_RPT_RX; debug++)
mt7915_mcu_fw_dbg_ctrl(dev, debug, dev->fw_debug);
for (debug = DEBUG_TXCMD; debug <= DEBUG_RPT_RX; debug++) {
ret = mt7915_mcu_fw_dbg_ctrl(dev, debug, !!dev->fw_debug_wm);
if (ret)
return ret;
}
/* WM CPU info record control */
mt76_clear(dev, MT_CPU_UTIL_CTRL, BIT(0));
mt76_wr(dev, MT_DIC_CMD_REG_CMD, BIT(2) | BIT(13) | !dev->fw_debug_wm);
mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR, BIT(5));
mt76_wr(dev, MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR, BIT(5));
return 0;
}
static int
mt7915_fw_debug_get(void *data, u64 *val)
mt7915_fw_debug_wm_get(void *data, u64 *val)
{
struct mt7915_dev *dev = data;
*val = dev->fw_debug;
*val = dev->fw_debug_wm;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7915_fw_debug_get,
mt7915_fw_debug_set, "%lld\n");
DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wm, mt7915_fw_debug_wm_get,
mt7915_fw_debug_wm_set, "%lld\n");
static int
mt7915_fw_debug_wa_set(void *data, u64 val)
{
struct mt7915_dev *dev = data;
int ret;
dev->fw_debug_wa = val ? MCU_FW_LOG_TO_HOST : 0;
ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, dev->fw_debug_wa);
if (ret)
return ret;
return mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), MCU_WA_PARAM_PDMA_RX,
!!dev->fw_debug_wa, 0);
}
static int
mt7915_fw_debug_wa_get(void *data, u64 *val)
{
struct mt7915_dev *dev = data;
*val = dev->fw_debug_wa;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug_wa, mt7915_fw_debug_wa_get,
mt7915_fw_debug_wa_set, "%lld\n");
static int
mt7915_fw_util_wm_show(struct seq_file *file, void *data)
{
struct mt7915_dev *dev = file->private;
if (dev->fw_debug_wm) {
seq_printf(file, "Busy: %u%% Peak busy: %u%%\n",
mt76_rr(dev, MT_CPU_UTIL_BUSY_PCT),
mt76_rr(dev, MT_CPU_UTIL_PEAK_BUSY_PCT));
seq_printf(file, "Idle count: %u Peak idle count: %u\n",
mt76_rr(dev, MT_CPU_UTIL_IDLE_CNT),
mt76_rr(dev, MT_CPU_UTIL_PEAK_IDLE_CNT));
}
return 0;
}
DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wm);
static int
mt7915_fw_util_wa_show(struct seq_file *file, void *data)
{
struct mt7915_dev *dev = file->private;
if (dev->fw_debug_wa)
return mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(QUERY),
MCU_WA_PARAM_CPU_UTIL, 0, 0);
return 0;
}
DEFINE_SHOW_ATTRIBUTE(mt7915_fw_util_wa);
static void
mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
......@@ -460,7 +534,12 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
debugfs_create_file("xmit-queues", 0400, dir, phy,
&mt7915_xmit_queues_fops);
debugfs_create_file("tx_stats", 0400, dir, phy, &mt7915_tx_stats_fops);
debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
debugfs_create_file("fw_debug_wm", 0600, dir, dev, &fops_fw_debug_wm);
debugfs_create_file("fw_debug_wa", 0600, dir, dev, &fops_fw_debug_wa);
debugfs_create_file("fw_util_wm", 0400, dir, dev,
&mt7915_fw_util_wm_fops);
debugfs_create_file("fw_util_wa", 0400, dir, dev,
&mt7915_fw_util_wa_fops);
debugfs_create_file("implicit_txbf", 0600, dir, dev,
&fops_implicit_txbf);
debugfs_create_file("txpower_sku", 0400, dir, phy,
......@@ -481,19 +560,71 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
#ifdef CONFIG_MAC80211_DEBUGFS
/** per-station debugfs **/
static int mt7915_sta_fixed_rate_set(void *data, u64 rate)
static ssize_t mt7915_sta_fixed_rate_set(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ieee80211_sta *sta = data;
struct ieee80211_sta *sta = file->private_data;
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
/* usage: <he ltf> <tx mode> <ldpc> <stbc> <bw> <gi> <nss> <mcs>
* <tx mode>: see enum mt76_phy_type
struct mt7915_dev *dev = msta->vif->phy->dev;
struct ieee80211_vif *vif;
struct sta_phy phy = {};
char buf[100];
int ret;
u32 field;
u8 i, gi, he_ltf;
if (count >= sizeof(buf))
return -EINVAL;
if (copy_from_user(buf, user_buf, count))
return -EFAULT;
if (count && buf[count - 1] == '\n')
buf[count - 1] = '\0';
else
buf[count] = '\0';
/* mode - cck: 0, ofdm: 1, ht: 2, gf: 3, vht: 4, he_su: 8, he_er: 9
* bw - bw20: 0, bw40: 1, bw80: 2, bw160: 3
* nss - vht: 1~4, he: 1~4, others: ignore
* mcs - cck: 0~4, ofdm: 0~7, ht: 0~32, vht: 0~9, he_su: 0~11, he_er: 0~2
* gi - (ht/vht) lgi: 0, sgi: 1; (he) 0.8us: 0, 1.6us: 1, 3.2us: 2
* ldpc - off: 0, on: 1
* stbc - off: 0, on: 1
* he_ltf - 1xltf: 0, 2xltf: 1, 4xltf: 2
*/
return mt7915_mcu_set_fixed_rate(msta->vif->phy->dev, sta, rate);
if (sscanf(buf, "%hhu %hhu %hhu %hhu %hhu %hhu %hhu %hhu",
&phy.type, &phy.bw, &phy.nss, &phy.mcs, &gi,
&phy.ldpc, &phy.stbc, &he_ltf) != 8) {
dev_warn(dev->mt76.dev,
"format: Mode BW NSS MCS (HE)GI LDPC STBC HE_LTF\n");
field = RATE_PARAM_AUTO;
goto out;
}
phy.ldpc = (phy.bw || phy.ldpc) * GENMASK(2, 0);
for (i = 0; i <= phy.bw; i++) {
phy.sgi |= gi << (i << sta->he_cap.has_he);
phy.he_ltf |= he_ltf << (i << sta->he_cap.has_he);
}
field = RATE_PARAM_FIXED;
out:
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy, field);
if (ret)
return -EFAULT;
return count;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_fixed_rate, NULL,
mt7915_sta_fixed_rate_set, "%llx\n");
static const struct file_operations fops_fixed_rate = {
.write = mt7915_sta_fixed_rate_set,
.open = simple_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static int
mt7915_queues_show(struct seq_file *s, void *data)
......
......@@ -89,7 +89,7 @@ bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask)
0, 5000);
}
static u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw)
u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw)
{
mt76_wr(dev, MT_WTBLON_TOP_WDUCR,
FIELD_PREP(MT_WTBLON_TOP_WDUCR_GROUP, (wcid >> 7)));
......@@ -2077,10 +2077,8 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
if (changed & (IEEE80211_RC_SUPP_RATES_CHANGED |
IEEE80211_RC_NSS_CHANGED |
IEEE80211_RC_BW_CHANGED)) {
mt7915_mcu_add_he(dev, vif, sta);
mt7915_mcu_add_rate_ctrl(dev, vif, sta);
}
IEEE80211_RC_BW_CHANGED))
mt7915_mcu_add_rate_ctrl(dev, vif, sta, true);
if (changed & IEEE80211_RC_SMPS_CHANGED)
mt7915_mcu_add_smps(dev, vif, sta);
......
......@@ -172,6 +172,9 @@ static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif)
int i;
for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) {
mvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI;
mvif->bitrate_mask.control[i].he_gi = GENMASK(7, 0);
mvif->bitrate_mask.control[i].he_ltf = GENMASK(7, 0);
mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0);
memset(mvif->bitrate_mask.control[i].ht_mcs, GENMASK(7, 0),
sizeof(mvif->bitrate_mask.control[i].ht_mcs));
......@@ -663,7 +666,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
if (ret)
return ret;
return mt7915_mcu_add_rate_ctrl(dev, vif, sta);
return mt7915_mcu_add_rate_ctrl(dev, vif, sta, false);
}
void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
......@@ -994,7 +997,6 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
{
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct mt7915_dev *dev = msta->vif->phy->dev;
struct ieee80211_hw *hw = msta->vif->phy->mt76->hw;
u32 *changed = data;
spin_lock_bh(&dev->sta_poll_lock);
......@@ -1002,8 +1004,6 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)
if (list_empty(&msta->rc_list))
list_add_tail(&msta->rc_list, &dev->sta_rc_list);
spin_unlock_bh(&dev->sta_poll_lock);
ieee80211_queue_work(hw, &dev->rc_work);
}
static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
......@@ -1011,7 +1011,11 @@ static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_sta *sta,
u32 changed)
{
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt7915_dev *dev = phy->dev;
mt7915_sta_rc_work(&changed, sta);
ieee80211_queue_work(hw, &dev->rc_work);
}
static int
......@@ -1019,22 +1023,22 @@ mt7915_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
enum nl80211_band band = mvif->phy->mt76->chandef.chan->band;
u32 changed;
if (mask->control[band].gi == NL80211_TXRATE_FORCE_LGI)
return -EINVAL;
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt7915_dev *dev = phy->dev;
u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED;
changed = IEEE80211_RC_SUPP_RATES_CHANGED;
mvif->bitrate_mask = *mask;
/* Update firmware rate control to add a boundary on top of table
* to limit the rate selection for each peer, so when set bitrates
* vht-mcs-5 1:9, which actually means nss = 1 mcs = 0~9. This only
* applies to data frames as for the other mgmt, mcast, bcast still
* use legacy rates as it is.
/* if multiple rates across different preambles are given we can
* reconfigure this info with all peers using sta_rec command with
* the below exception cases.
* - single rate : if a rate is passed along with different preambles,
* we select the highest one as fixed rate. i.e VHT MCS for VHT peers.
* - multiple rates: if it's not in range format i.e 0-{7,8,9} for VHT
* then multiple MCS setting (MCS 4,5,6) is not supported.
*/
ieee80211_iterate_stations_atomic(hw, mt7915_sta_rc_work, &changed);
ieee80211_queue_work(hw, &dev->rc_work);
return 0;
}
......
......@@ -416,8 +416,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);
}
static int
mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3)
int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3)
{
struct {
__le32 args[3];
......@@ -429,7 +428,7 @@ mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3)
},
};
return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), false);
}
static void
......@@ -2050,6 +2049,129 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
}
int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
void *data, u32 field)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct sta_phy *phy = data;
struct sta_rec_ra_fixed *ra;
struct sk_buff *skb;
struct tlv *tlv;
int len = sizeof(struct sta_req_hdr) + sizeof(*ra);
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
tlv = mt7915_mcu_add_tlv(skb, STA_REC_RA_UPDATE, sizeof(*ra));
ra = (struct sta_rec_ra_fixed *)tlv;
switch (field) {
case RATE_PARAM_AUTO:
break;
case RATE_PARAM_FIXED:
case RATE_PARAM_FIXED_MCS:
case RATE_PARAM_FIXED_GI:
case RATE_PARAM_FIXED_HE_LTF:
ra->phy = *phy;
break;
default:
break;
}
ra->field = cpu_to_le32(field);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
static int
mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask;
enum nl80211_band band = chandef->chan->band;
struct sta_phy phy = {};
int ret, nrates = 0;
#define __sta_phy_bitrate_mask_check(_mcs, _gi, _he) \
do { \
u8 i, gi = mask->control[band]._gi; \
gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \
for (i = 0; i <= sta->bandwidth; i++) { \
phy.sgi |= gi << (i << (_he)); \
phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\
} \
for (i = 0; i < ARRAY_SIZE(mask->control[band]._mcs); i++) \
nrates += hweight16(mask->control[band]._mcs[i]); \
phy.mcs = ffs(mask->control[band]._mcs[0]) - 1; \
} while (0)
if (sta->he_cap.has_he) {
__sta_phy_bitrate_mask_check(he_mcs, he_gi, 1);
} else if (sta->vht_cap.vht_supported) {
__sta_phy_bitrate_mask_check(vht_mcs, gi, 0);
} else if (sta->ht_cap.ht_supported) {
__sta_phy_bitrate_mask_check(ht_mcs, gi, 0);
} else {
nrates = hweight32(mask->control[band].legacy);
phy.mcs = ffs(mask->control[band].legacy) - 1;
}
#undef __sta_phy_bitrate_mask_check
/* fall back to auto rate control */
if (mask->control[band].gi == NL80211_TXRATE_DEFAULT_GI &&
mask->control[band].he_gi == GENMASK(7, 0) &&
mask->control[band].he_ltf == GENMASK(7, 0) &&
nrates != 1)
return 0;
/* fixed single rate */
if (nrates == 1) {
ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy,
RATE_PARAM_FIXED_MCS);
if (ret)
return ret;
}
/* fixed GI */
if (mask->control[band].gi != NL80211_TXRATE_DEFAULT_GI ||
mask->control[band].he_gi != GENMASK(7, 0)) {
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
u32 addr;
/* firmware updates only TXCMD but doesn't take WTBL into
* account, so driver should update here to reflect the
* actual txrate hardware sends out.
*/
addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7);
if (sta->he_cap.has_he)
mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi);
else
mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi);
ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy,
RATE_PARAM_FIXED_GI);
if (ret)
return ret;
}
/* fixed HE_LTF */
if (mask->control[band].he_ltf != GENMASK(7, 0)) {
ret = mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, &phy,
RATE_PARAM_FIXED_HE_LTF);
if (ret)
return ret;
}
return 0;
}
static void
mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
struct ieee80211_vif *vif, struct ieee80211_sta *sta)
......@@ -2092,8 +2214,6 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
}
if (sta->ht_cap.ht_supported) {
const u8 *mcs_mask = mask->control[band].ht_mcs;
ra->supp_mode |= MODE_HT;
ra->af = sta->ht_cap.ampdu_factor;
ra->ht_gf = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD);
......@@ -2111,12 +2231,12 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING))
cap |= STA_CAP_LDPC;
mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs, mcs_mask);
mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs,
mask->control[band].ht_mcs);
ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs;
}
if (sta->vht_cap.vht_supported) {
const u16 *mcs_mask = mask->control[band].vht_mcs;
u8 af;
ra->supp_mode |= MODE_VHT;
......@@ -2137,7 +2257,8 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC))
cap |= STA_CAP_VHT_LDPC;
mt7915_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs, mcs_mask);
mt7915_mcu_set_sta_vht_mcs(sta, ra->supp_vht_mcs,
mask->control[band].vht_mcs);
}
if (sta->he_cap.has_he) {
......@@ -2149,44 +2270,40 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
}
int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
struct ieee80211_sta *sta, bool changed)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct sk_buff *skb;
int len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_ra);
int ret;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT7915_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
mt7915_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct sk_buff *skb;
int len;
if (!sta->he_cap.has_he)
return 0;
len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_he);
/* firmware rc algorithm refers to sta_rec_he for HE control.
* once dev->rc_work changes the settings driver should also
* update sta_rec_he here.
*/
if (sta->he_cap.has_he && changed)
mt7915_mcu_sta_he_tlv(skb, sta, vif);
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
/* sta_rec_ra accommodates BW, NSS and only MCS range format
* i.e 0-{7,8,9} for VHT.
*/
mt7915_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta);
mt7915_mcu_sta_he_tlv(skb, sta, vif);
ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
if (ret)
return ret;
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
/* sta_rec_ra_fixed accommodates single rate, (HE)GI and HE_LTE,
* and updates as peer fixed rate parameters, which overrides
* sta_rec_ra and firmware rate control algorithm.
*/
return mt7915_mcu_add_rate_ctrl_fixed(dev, vif, sta);
}
static int
......@@ -2443,9 +2560,8 @@ mt7915_mcu_beacon_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif,
len);
if (ie && ie[1] >= sizeof(*ht)) {
ht = (void *)(ie + 2);
bc = le32_to_cpu(ht->cap_info);
vc->ldpc |= !!(bc & IEEE80211_HT_CAP_LDPC_CODING);
vc->ldpc |= !!(le16_to_cpu(ht->cap_info) &
IEEE80211_HT_CAP_LDPC_CODING);
}
ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, mgmt->u.beacon.variable,
......@@ -2863,7 +2979,7 @@ static int mt7915_load_firmware(struct mt7915_dev *dev)
return 0;
}
int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 ctrl)
int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl)
{
struct {
u8 ctrl_val;
......@@ -2872,6 +2988,10 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 ctrl)
.ctrl_val = ctrl
};
if (type == MCU_FW_LOG_WA)
return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(FW_LOG_2_HOST),
&data, sizeof(data), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(FW_LOG_2_HOST), &data,
sizeof(data), true);
}
......@@ -2984,7 +3104,11 @@ int mt7915_mcu_init(struct mt7915_dev *dev)
return ret;
set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
ret = mt7915_mcu_fw_log_2_host(dev, 0);
ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WM, 0);
if (ret)
return ret;
ret = mt7915_mcu_fw_log_2_host(dev, MCU_FW_LOG_WA, 0);
if (ret)
return ret;
......
......@@ -229,6 +229,11 @@ enum {
MCU_S2D_H2CN
};
enum {
MCU_FW_LOG_WM,
MCU_FW_LOG_WA,
MCU_FW_LOG_TO_HOST,
};
#define __MCU_CMD_FIELD_ID GENMASK(7, 0)
#define __MCU_CMD_FIELD_EXT_ID GENMASK(15, 8)
......@@ -304,6 +309,8 @@ enum {
};
enum {
MCU_WA_PARAM_PDMA_RX = 0x04,
MCU_WA_PARAM_CPU_UTIL = 0x0b,
MCU_WA_PARAM_RED = 0x0e,
};
......@@ -886,7 +893,7 @@ struct sta_rec_sec {
struct sec_key key[2];
} __packed;
struct ra_phy {
struct sta_phy {
u8 type;
u8 flag;
u8 stbc;
......@@ -930,7 +937,7 @@ struct sta_rec_ra {
__le32 sta_cap;
struct ra_phy phy;
struct sta_phy phy;
} __packed;
struct sta_rec_ra_fixed {
......@@ -943,7 +950,7 @@ struct sta_rec_ra_fixed {
u8 op_vht_rx_nss;
u8 op_vht_rx_nss_type;
struct ra_phy phy;
struct sta_phy phy;
u8 spe_en;
u8 short_preamble;
......@@ -951,8 +958,14 @@ struct sta_rec_ra_fixed {
u8 mmps_mode;
} __packed;
#define RATE_PARAM_FIXED 3
#define RATE_PARAM_AUTO 20
enum {
RATE_PARAM_FIXED = 3,
RATE_PARAM_FIXED_HE_LTF = 7,
RATE_PARAM_FIXED_MCS,
RATE_PARAM_FIXED_GI = 11,
RATE_PARAM_AUTO = 20,
};
#define RATE_CFG_MCS GENMASK(3, 0)
#define RATE_CFG_NSS GENMASK(7, 4)
#define RATE_CFG_GI GENMASK(11, 8)
......
......@@ -34,6 +34,9 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
u32 mapped;
u32 size;
} fixed_map[] = {
{ 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */
{ 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure regs) */
{ 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */
{ 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */
{ 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */
{ 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */
......
......@@ -270,8 +270,9 @@ struct mt7915_dev {
bool dbdc_support;
bool flash_mode;
bool fw_debug;
bool ibf;
u8 fw_debug_wm;
u8 fw_debug_wa;
void *cal;
......@@ -409,17 +410,17 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
bool enable);
int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int mt7915_mcu_add_he(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
struct ieee80211_sta *sta, bool changed);
int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
int mt7915_set_channel(struct mt7915_phy *phy);
int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd);
int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif);
int mt7915_mcu_update_edca(struct mt7915_dev *dev, void *req);
int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
struct ieee80211_sta *sta, u32 rate);
int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
void *data, u32 field);
int mt7915_mcu_set_eeprom(struct mt7915_dev *dev);
int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset);
int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
......@@ -449,7 +450,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct rate_info *rate);
int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev, enum mt7915_rdd_cmd cmd,
u8 index, u8 rx_sel, u8 val);
int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 ctrl);
int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3);
int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl);
int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level);
void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb);
void mt7915_mcu_exit(struct mt7915_dev *dev);
......@@ -480,6 +482,7 @@ static inline void mt7915_irq_disable(struct mt7915_dev *dev, u32 mask)
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
}
u32 mt7915_mac_wtbl_lmac_addr(struct mt7915_dev *dev, u16 wcid, u8 dw);
bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask);
void mt7915_mac_reset_counters(struct mt7915_phy *phy);
void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy);
......
......@@ -528,6 +528,18 @@
#define MT_HIF_REMAP_L2_BASE GENMASK(31, 12)
#define MT_HIF_REMAP_BASE_L2 0x00000
#define MT_DIC_CMD_REG_BASE 0x41f000
#define MT_DIC_CMD_REG(ofs) (MT_DIC_CMD_REG_BASE + (ofs))
#define MT_DIC_CMD_REG_CMD MT_DIC_CMD_REG(0x10)
#define MT_CPU_UTIL_BASE 0x41f030
#define MT_CPU_UTIL(ofs) (MT_CPU_UTIL_BASE + (ofs))
#define MT_CPU_UTIL_BUSY_PCT MT_CPU_UTIL(0x00)
#define MT_CPU_UTIL_PEAK_BUSY_PCT MT_CPU_UTIL(0x04)
#define MT_CPU_UTIL_IDLE_CNT MT_CPU_UTIL(0x08)
#define MT_CPU_UTIL_PEAK_IDLE_CNT MT_CPU_UTIL(0x0c)
#define MT_CPU_UTIL_CTRL MT_CPU_UTIL(0x1c)
#define MT_SWDEF_BASE 0x41f200
#define MT_SWDEF(ofs) (MT_SWDEF_BASE + (ofs))
#define MT_SWDEF_MODE MT_SWDEF(0x3c)
......@@ -590,4 +602,9 @@
#define MT_WF_PHY_RXTD12_IRPI_SW_CLR_ONLY BIT(18)
#define MT_WF_PHY_RXTD12_IRPI_SW_CLR BIT(29)
#define MT_MCU_WM_CIRQ_BASE 0x89010000
#define MT_MCU_WM_CIRQ(ofs) (MT_MCU_WM_CIRQ_BASE + (ofs))
#define MT_MCU_WM_CIRQ_IRQ_MASK_CLR_ADDR MT_MCU_WM_CIRQ(0x80)
#define MT_MCU_WM_CIRQ_IRQ_SOFT_ADDR MT_MCU_WM_CIRQ(0xc0)
#endif
......@@ -62,7 +62,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
hw->vif_data_size = sizeof(struct mt7921_vif);
wiphy->iface_combinations = if_comb;
wiphy->flags &= ~WIPHY_FLAG_IBSS_RSN;
wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN | WIPHY_FLAG_4ADDR_AP |
WIPHY_FLAG_4ADDR_STATION);
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
......
......@@ -70,17 +70,15 @@ mt76_worker_setup(struct ieee80211_hw *hw, struct mt76_worker *w,
if (fn)
w->fn = fn;
w->task = kthread_create(__mt76_worker_fn, w, "mt76-%s %s",
name, dev_name);
w->task = kthread_run(__mt76_worker_fn, w,
"mt76-%s %s", name, dev_name);
ret = PTR_ERR_OR_ZERO(w->task);
if (ret) {
if (IS_ERR(w->task)) {
ret = PTR_ERR(w->task);
w->task = NULL;
return ret;
}
wake_up_process(w->task);
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment