mt76 patches for 5.17

* decap offload fixes
 * mt7915 fixes
 * mt7921 fixes
 * eeprom fixes
 * powersave handling fixes
 * SAR support
 * code cleanups
 -----BEGIN PGP SIGNATURE-----
 Comment: GPGTools - http://gpgtools.org
 
 iEYEABECAAYFAmG/QOQACgkQ130UHQKnbvVdrgCgxjh7lVj2xb7x8HmFrXinhEXg
 UPMAnRinUaMPKoSAGcDQYRvzk6BiaAKe
 =/D5w
 -----END PGP SIGNATURE-----

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

mt76 patches for 5.17

* decap offload fixes
* mt7915 fixes
* mt7921 fixes
* eeprom fixes
* powersave handling fixes
* SAR support
* code cleanups
This commit is contained in:
Kalle Valo 2021-12-20 20:38:06 +02:00
commit d8f9bb98cb
60 changed files with 2110 additions and 1820 deletions

View file

@ -74,14 +74,15 @@ EXPORT_SYMBOL_GPL(mt76_queues_read);
static int mt76_rx_queues_read(struct seq_file *s, void *data)
{
struct mt76_dev *dev = dev_get_drvdata(s->private);
int i;
int i, queued;
seq_puts(s, " queue | hw-queued | head | tail |\n");
mt76_for_each_q_rx(dev, i) {
struct mt76_queue *q = &dev->q_rx[i];
queued = mt76_is_usb(dev) ? q->ndesc - q->queued : q->queued;
seq_printf(s, " %9d | %9d | %9d | %9d |\n",
i, q->queued, q->head, q->tail);
i, queued, q->head, q->tail);
}
return 0;

View file

@ -572,9 +572,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
if (data_len < len + q->buf_offset) {
dev_kfree_skb(q->rx_head);
q->rx_head = NULL;
skb_free_frag(data);
continue;
goto free_frag;
}
if (q->rx_head) {
@ -582,11 +580,14 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
continue;
}
if (!more && dev->drv->rx_check &&
!(dev->drv->rx_check(dev, data, len)))
goto free_frag;
skb = build_skb(data, q->buf_size);
if (!skb) {
skb_free_frag(data);
continue;
}
if (!skb)
goto free_frag;
skb_reserve(skb, q->buf_offset);
if (q == &dev->q_rx[MT_RXQ_MCU]) {
@ -603,6 +604,10 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
}
dev->drv->rx_skb(dev, q - dev->q_rx, skb);
continue;
free_frag:
skb_free_frag(data);
}
mt76_dma_rx_fill(dev, q);

View file

@ -65,6 +65,8 @@ 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 (mtd_is_bitflip(ret))
ret = 0;
if (ret) {
dev_err(dev->dev, "reading EEPROM from mtd %s failed: %i\n",
part, ret);

View file

@ -185,7 +185,6 @@ const struct cfg80211_sar_capa mt76_sar_capa = {
.num_freq_ranges = ARRAY_SIZE(mt76_sar_freq_ranges),
.freq_ranges = &mt76_sar_freq_ranges[0],
};
EXPORT_SYMBOL_GPL(mt76_sar_capa);
static int mt76_led_init(struct mt76_dev *dev)
{
@ -393,7 +392,7 @@ mt76_check_sband(struct mt76_phy *phy, struct mt76_sband *msband,
phy->hw->wiphy->bands[band] = NULL;
}
static void
static int
mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
{
struct mt76_dev *dev = phy->dev;
@ -411,8 +410,15 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
wiphy->available_antennas_tx = dev->phy.antenna_mask;
wiphy->available_antennas_rx = dev->phy.antenna_mask;
wiphy->available_antennas_tx = phy->antenna_mask;
wiphy->available_antennas_rx = phy->antenna_mask;
wiphy->sar_capa = &mt76_sar_capa;
phy->frp = devm_kcalloc(dev->dev, wiphy->sar_capa->num_freq_ranges,
sizeof(struct mt76_freq_range_power),
GFP_KERNEL);
if (!phy->frp)
return -ENOMEM;
hw->txq_data_size = sizeof(struct mt76_txq);
hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL;
@ -432,6 +438,8 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS);
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
return 0;
}
struct mt76_phy *
@ -472,7 +480,9 @@ int mt76_register_phy(struct mt76_phy *phy, bool vht,
{
int ret;
mt76_phy_init(phy, phy->hw);
ret = mt76_phy_init(phy, phy->hw);
if (ret)
return ret;
if (phy->cap.has_2ghz) {
ret = mt76_init_sband_2g(phy, rates, n_rates);
@ -591,7 +601,9 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,
int ret;
dev_set_drvdata(dev->dev, dev);
mt76_phy_init(phy, hw);
ret = mt76_phy_init(phy, hw);
if (ret)
return ret;
if (phy->cap.has_2ghz) {
ret = mt76_init_sband_2g(phy, rates, n_rates);
@ -1163,10 +1175,12 @@ mt76_check_sta(struct mt76_dev *dev, struct sk_buff *skb)
if (ps)
set_bit(MT_WCID_FLAG_PS, &wcid->flags);
else
clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
dev->drv->sta_ps(dev, sta, ps);
if (!ps)
clear_bit(MT_WCID_FLAG_PS, &wcid->flags);
ieee80211_sta_ps_transition(sta, ps);
}
@ -1348,6 +1362,59 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
EXPORT_SYMBOL_GPL(mt76_get_txpower);
int mt76_init_sar_power(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
struct mt76_phy *phy = hw->priv;
const struct cfg80211_sar_capa *capa = hw->wiphy->sar_capa;
int i;
if (sar->type != NL80211_SAR_TYPE_POWER || !sar->num_sub_specs)
return -EINVAL;
for (i = 0; i < sar->num_sub_specs; i++) {
u32 index = sar->sub_specs[i].freq_range_index;
/* SAR specifies power limitaton in 0.25dbm */
s32 power = sar->sub_specs[i].power >> 1;
if (power > 127 || power < -127)
power = 127;
phy->frp[index].range = &capa->freq_ranges[index];
phy->frp[index].power = power;
}
return 0;
}
EXPORT_SYMBOL_GPL(mt76_init_sar_power);
int mt76_get_sar_power(struct mt76_phy *phy,
struct ieee80211_channel *chan,
int power)
{
const struct cfg80211_sar_capa *capa = phy->hw->wiphy->sar_capa;
int freq, i;
if (!capa || !phy->frp)
return power;
if (power > 127 || power < -127)
power = 127;
freq = ieee80211_channel_to_frequency(chan->hw_value, chan->band);
for (i = 0 ; i < capa->num_freq_ranges; i++) {
if (phy->frp[i].range &&
freq >= phy->frp[i].range->start_freq &&
freq < phy->frp[i].range->end_freq) {
power = min_t(int, phy->frp[i].power, power);
break;
}
}
return power;
}
EXPORT_SYMBOL_GPL(mt76_get_sar_power);
static void
__mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
@ -1494,7 +1561,6 @@ EXPORT_SYMBOL_GPL(mt76_init_queue);
u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx)
{
int offset = 0;
struct ieee80211_rate *rate;
if (phy->chandef.chan->band != NL80211_BAND_2GHZ)
offset = 4;
@ -1503,9 +1569,11 @@ u16 mt76_calculate_default_rate(struct mt76_phy *phy, int rateidx)
if (rateidx < 0)
rateidx = 0;
rate = &mt76_rates[offset + rateidx];
rateidx += offset;
if (rateidx >= ARRAY_SIZE(mt76_rates))
rateidx = offset;
return rate->hw_value;
return mt76_rates[rateidx].hw_value;
}
EXPORT_SYMBOL_GPL(mt76_calculate_default_rate);

View file

@ -373,6 +373,8 @@ struct mt76_driver_ops {
bool (*tx_status_data)(struct mt76_dev *dev, u8 *update);
bool (*rx_check)(struct mt76_dev *dev, void *data, int len);
void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q,
struct sk_buff *skb);
@ -495,6 +497,8 @@ struct mt76_usb {
};
#define MT76S_XMIT_BUF_SZ (16 * PAGE_SIZE)
#define MT76S_NUM_TX_ENTRIES 256
#define MT76S_NUM_RX_ENTRIES 512
struct mt76_sdio {
struct mt76_worker txrx_worker;
struct mt76_worker status_worker;
@ -599,6 +603,8 @@ struct mt76_testmode_data {
u8 tx_power[4];
u8 tx_power_control;
u8 addr[3][ETH_ALEN];
u32 tx_pending;
u32 tx_queued;
u16 tx_queued_limit;
@ -808,7 +814,6 @@ struct mt76_ethtool_worker_info {
}
extern struct ieee80211_rate mt76_rates[12];
extern const struct cfg80211_sar_capa mt76_sar_capa;
#define __mt76_rr(dev, ...) (dev)->bus->rr((dev), __VA_ARGS__)
#define __mt76_wr(dev, ...) (dev)->bus->wr((dev), __VA_ARGS__)
@ -1157,6 +1162,11 @@ int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy);
int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
int *dbm);
int mt76_init_sar_power(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
int mt76_get_sar_power(struct mt76_phy *phy,
struct ieee80211_channel *chan,
int power);
void mt76_csa_check(struct mt76_dev *dev);
void mt76_csa_finish(struct mt76_dev *dev);

View file

@ -202,10 +202,11 @@ void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort)
FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, port) |
FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, queue));
WARN_ON_ONCE(!mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY,
0, 5000));
mt76_poll(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY, 0, 15000);
}
WARN_ON_ONCE(mt76_rr(dev, MT_DMA_FQCR0) & MT_DMA_FQCR0_BUSY);
mt76_wr(dev, MT_TX_ABORT, 0);
mt7603_wtbl_set_skip_tx(dev, idx, false);
@ -525,6 +526,10 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
if (rxd2 & MT_RXD2_NORMAL_TKIP_MIC_ERR)
status->flag |= RX_FLAG_MMIC_ERROR;
/* ICV error or CCMP/BIP/WPI MIC error */
if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
status->flag |= RX_FLAG_ONLY_MONITOR;
if (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2) != 0 &&
!(rxd2 & (MT_RXD2_NORMAL_CLM | MT_RXD2_NORMAL_CM))) {
status->flag |= RX_FLAG_DECRYPTED;

View file

@ -133,13 +133,15 @@ void mt7603_init_edcca(struct mt7603_dev *dev)
}
static int
mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
mt7603_set_channel(struct ieee80211_hw *hw, struct cfg80211_chan_def *def)
{
struct mt7603_dev *dev = hw->priv;
u8 *rssi_data = (u8 *)dev->mt76.eeprom.data;
int idx, ret;
u8 bw = MT_BW_20;
bool failed = false;
ieee80211_stop_queues(hw);
cancel_delayed_work_sync(&dev->mphy.mac_work);
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
@ -205,9 +207,28 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
if (failed)
mt7603_mac_work(&dev->mphy.mac_work.work);
ieee80211_wake_queues(hw);
return ret;
}
static int mt7603_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
struct mt7603_dev *dev = hw->priv;
struct mt76_phy *mphy = &dev->mphy;
int err;
if (!cfg80211_chandef_valid(&mphy->chandef))
return -EINVAL;
err = mt76_init_sar_power(hw, sar);
if (err)
return err;
return mt7603_set_channel(hw, &mphy->chandef);
}
static int
mt7603_config(struct ieee80211_hw *hw, u32 changed)
{
@ -215,11 +236,8 @@ mt7603_config(struct ieee80211_hw *hw, u32 changed)
int ret = 0;
if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
IEEE80211_CONF_CHANGE_POWER)) {
ieee80211_stop_queues(hw);
ret = mt7603_set_channel(dev, &hw->conf.chandef);
ieee80211_wake_queues(hw);
}
IEEE80211_CONF_CHANGE_POWER))
ret = mt7603_set_channel(hw, &hw->conf.chandef);
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
mutex_lock(&dev->mt76.mutex);
@ -700,6 +718,7 @@ const struct ieee80211_ops mt7603_ops = {
.set_tim = mt76_set_tim,
.get_survey = mt76_get_survey,
.get_antenna = mt76_get_antenna,
.set_sar_specs = mt7603_set_sar_specs,
};
MODULE_LICENSE("Dual BSD/GPL");

View file

@ -403,7 +403,7 @@ int mt7603_mcu_set_channel(struct mt7603_dev *dev)
.tx_streams = n_chains,
.rx_streams = n_chains,
};
s8 tx_power;
s8 tx_power = hw->conf.power_level * 2;
int i, ret;
if (dev->mphy.chandef.width == NL80211_CHAN_WIDTH_40) {
@ -414,7 +414,7 @@ int mt7603_mcu_set_channel(struct mt7603_dev *dev)
req.center_chan -= 2;
}
tx_power = hw->conf.power_level * 2;
tx_power = mt76_get_sar_power(&dev->mphy, chandef->chan, tx_power);
if (dev->mphy.antenna_mask == 3)
tx_power -= 6;
tx_power = min(tx_power, dev->tx_power_limit);

View file

@ -359,6 +359,9 @@ mt7615_queues_acq(struct seq_file *s, void *data)
int acs = i / MT7615_MAX_WMM_SETS;
u32 ctrl, val, qlen = 0;
if (wmm_idx == 3 && is_mt7663(&dev->mt76))
continue;
val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx));
ctrl = BIT(31) | BIT(15) | (acs << 8);

View file

@ -194,6 +194,7 @@ mt7615_check_offload_capability(struct mt7615_dev *dev)
ieee80211_hw_set(hw, SUPPORTS_PS);
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
wiphy->flags &= ~WIPHY_FLAG_4ADDR_STATION;
wiphy->max_remain_on_channel_duration = 5000;
wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |

View file

@ -249,6 +249,82 @@ static void mt7615_mac_fill_tm_rx(struct mt7615_phy *phy, __le32 *rxv)
#endif
}
/* The HW does not translate the mac header to 802.3 for mesh point */
static int mt7615_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
struct mt7615_sta *msta = (struct mt7615_sta *)status->wcid;
struct ieee80211_sta *sta;
struct ieee80211_vif *vif;
struct ieee80211_hdr hdr;
struct ethhdr eth_hdr;
__le32 *rxd = (__le32 *)skb->data;
__le32 qos_ctrl, ht_ctrl;
if (FIELD_GET(MT_RXD1_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[1])) !=
MT_RXD1_NORMAL_U2M)
return -EINVAL;
if (!(le32_to_cpu(rxd[0]) & MT_RXD0_NORMAL_GROUP_4))
return -EINVAL;
if (!msta || !msta->vif)
return -EINVAL;
sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
/* store the info from RXD and ethhdr to avoid being overridden */
memcpy(&eth_hdr, skb->data + hdr_gap, sizeof(eth_hdr));
hdr.frame_control = FIELD_GET(MT_RXD4_FRAME_CONTROL, rxd[4]);
hdr.seq_ctrl = FIELD_GET(MT_RXD6_SEQ_CTRL, rxd[6]);
qos_ctrl = FIELD_GET(MT_RXD6_QOS_CTL, rxd[6]);
ht_ctrl = FIELD_GET(MT_RXD7_HT_CONTROL, rxd[7]);
hdr.duration_id = 0;
ether_addr_copy(hdr.addr1, vif->addr);
ether_addr_copy(hdr.addr2, sta->addr);
switch (le16_to_cpu(hdr.frame_control) &
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case 0:
ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
break;
case IEEE80211_FCTL_FROMDS:
ether_addr_copy(hdr.addr3, eth_hdr.h_source);
break;
case IEEE80211_FCTL_TODS:
ether_addr_copy(hdr.addr3, eth_hdr.h_dest);
break;
case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS:
ether_addr_copy(hdr.addr3, eth_hdr.h_dest);
ether_addr_copy(hdr.addr4, eth_hdr.h_source);
break;
default:
break;
}
skb_pull(skb, hdr_gap + sizeof(struct ethhdr) - 2);
if (eth_hdr.h_proto == htons(ETH_P_AARP) ||
eth_hdr.h_proto == htons(ETH_P_IPX))
ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
else if (eth_hdr.h_proto >= htons(ETH_P_802_3_MIN))
ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
else
skb_pull(skb, 2);
if (ieee80211_has_order(hdr.frame_control))
memcpy(skb_push(skb, 2), &ht_ctrl, 2);
if (ieee80211_is_data_qos(hdr.frame_control))
memcpy(skb_push(skb, 2), &qos_ctrl, 2);
if (ieee80211_has_a4(hdr.frame_control))
memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
else
memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6);
status->flag &= ~(RX_FLAG_RADIOTAP_HE | RX_FLAG_RADIOTAP_HE_MU);
return 0;
}
static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
@ -263,6 +339,7 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
u32 rxd2 = le32_to_cpu(rxd[2]);
u32 csum_mask = MT_RXD0_NORMAL_IP_SUM | MT_RXD0_NORMAL_UDP_TCP_SUM;
bool unicast, hdr_trans, remove_pad, insert_ccmp_hdr = false;
u16 hdr_gap;
int phy_idx;
int i, idx;
u8 chfreq, amsdu_info, qos_ctl = 0;
@ -286,9 +363,16 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
return -EINVAL;
hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_CM))
return -EINVAL;
/* ICV error or CCMP/BIP/WPI MIC error */
if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
status->flag |= RX_FLAG_ONLY_MONITOR;
unicast = (rxd1 & MT_RXD1_NORMAL_ADDR_TYPE) == MT_RXD1_NORMAL_U2M;
idx = FIELD_GET(MT_RXD2_NORMAL_WLAN_IDX, rxd2);
hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
status->wcid = mt7615_rx_get_wcid(dev, idx, unicast);
if (status->wcid) {
@ -503,16 +587,42 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
return -EINVAL;
}
skb_pull(skb, (u8 *)rxd - skb->data + 2 * remove_pad);
amsdu_info = FIELD_GET(MT_RXD1_NORMAL_PAYLOAD_FORMAT, rxd1);
status->amsdu = !!amsdu_info;
if (status->amsdu) {
status->first_amsdu = amsdu_info == MT_RXD1_FIRST_AMSDU_FRAME;
status->last_amsdu = amsdu_info == MT_RXD1_LAST_AMSDU_FRAME;
if (!hdr_trans) {
memmove(skb->data + 2, skb->data,
ieee80211_get_hdrlen_from_skb(skb));
}
hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad;
if (hdr_trans && ieee80211_has_morefrags(fc)) {
if (mt7615_reverse_frag0_hdr_trans(skb, hdr_gap))
return -EINVAL;
hdr_trans = false;
} else {
int pad_start = 0;
skb_pull(skb, hdr_gap);
if (!hdr_trans && status->amsdu) {
pad_start = ieee80211_get_hdrlen_from_skb(skb);
} else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR)) {
/*
* When header translation failure is indicated,
* the hardware will insert an extra 2-byte field
* containing the data length after the protocol
* type field.
*/
pad_start = 12;
if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q)
pad_start += 4;
if (get_unaligned_be16(skb->data + pad_start) !=
skb->len - pad_start - 2)
pad_start = 0;
}
if (pad_start) {
memmove(skb->data + 2, skb->data, pad_start);
skb_pull(skb, 2);
}
}

View file

@ -86,6 +86,8 @@ enum rx_pkt_type {
#define MT_RXD6_SEQ_CTRL GENMASK(15, 0)
#define MT_RXD6_QOS_CTL GENMASK(31, 16)
#define MT_RXD7_HT_CONTROL GENMASK(31, 0)
#define MT_RXV1_ACID_DET_H BIT(31)
#define MT_RXV1_ACID_DET_L BIT(30)
#define MT_RXV1_VHTA2_B8_B3 GENMASK(29, 24)

View file

@ -73,7 +73,7 @@ static int mt7615_start(struct ieee80211_hw *hw)
goto out;
}
ret = mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
ret = mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
if (ret)
goto out;
@ -141,9 +141,6 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask)
if (i)
return i - 1;
if (type != NL80211_IFTYPE_STATION)
break;
/* next, try to find a free repeater entry for the sta */
i = get_free_idx(mask >> REPEATER_BSSID_START, 0,
REPEATER_BSSID_MAX - REPEATER_BSSID_START);
@ -211,11 +208,9 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
mvif->mt76.omac_idx = idx;
mvif->mt76.band_idx = ext_phy;
if (mt7615_ext_phy(dev))
mvif->mt76.wmm_idx = ext_phy * (MT7615_MAX_WMM_SETS / 2) +
mvif->mt76.idx % (MT7615_MAX_WMM_SETS / 2);
else
mvif->mt76.wmm_idx = mvif->mt76.idx % MT7615_MAX_WMM_SETS;
mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
if (ext_phy)
mvif->mt76.wmm_idx += 2;
dev->mt76.vif_mask |= BIT(mvif->mt76.idx);
dev->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
@ -331,7 +326,7 @@ int mt7615_set_channel(struct mt7615_phy *phy)
goto out;
}
ret = mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD_CHANNEL_SWITCH);
ret = mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));
if (ret)
goto out;

View file

@ -87,7 +87,7 @@ struct mt7663_fw_buf {
void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
int cmd, int *wait_seq)
{
int txd_len, mcu_cmd = cmd & MCU_CMD_MASK;
int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
struct mt7615_uni_txd *uni_txd;
struct mt7615_mcu_txd *mcu_txd;
u8 seq, q_idx, pkt_fmt;
@ -103,10 +103,10 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
if (wait_seq)
*wait_seq = seq;
txd_len = cmd & MCU_UNI_PREFIX ? sizeof(*uni_txd) : sizeof(*mcu_txd);
txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);
txd = (__le32 *)skb_push(skb, txd_len);
if (cmd != MCU_CMD_FW_SCATTER) {
if (cmd != MCU_CMD(FW_SCATTER)) {
q_idx = MT_TX_MCU_PORT_RX_Q0;
pkt_fmt = MT_TX_TYPE_CMD;
} else {
@ -124,7 +124,7 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
FIELD_PREP(MT_TXD1_PKT_FMT, pkt_fmt);
txd[1] = cpu_to_le32(val);
if (cmd & MCU_UNI_PREFIX) {
if (cmd & __MCU_CMD_FIELD_UNI) {
uni_txd = (struct mt7615_uni_txd *)txd;
uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));
uni_txd->option = MCU_CMD_UNI_EXT_ACK;
@ -142,28 +142,17 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
mcu_txd->s2d_index = MCU_S2D_H2N;
mcu_txd->pkt_type = MCU_PKT_ID;
mcu_txd->seq = seq;
mcu_txd->cid = mcu_cmd;
mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
switch (cmd & ~MCU_CMD_MASK) {
case MCU_FW_PREFIX:
if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) {
if (cmd & __MCU_CMD_FIELD_QUERY)
mcu_txd->set_query = MCU_Q_QUERY;
else
mcu_txd->set_query = MCU_Q_SET;
mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid;
} else {
mcu_txd->set_query = MCU_Q_NA;
mcu_txd->cid = mcu_cmd;
break;
case MCU_CE_PREFIX:
if (cmd & MCU_QUERY_MASK)
mcu_txd->set_query = MCU_Q_QUERY;
else
mcu_txd->set_query = MCU_Q_SET;
mcu_txd->cid = mcu_cmd;
break;
default:
mcu_txd->cid = MCU_CMD_EXT_CID;
if (cmd & MCU_QUERY_PREFIX)
mcu_txd->set_query = MCU_Q_QUERY;
else
mcu_txd->set_query = MCU_Q_SET;
mcu_txd->ext_cid = mcu_cmd;
mcu_txd->ext_cid_ack = 1;
break;
}
}
EXPORT_SYMBOL_GPL(mt7615_mcu_fill_msg);
@ -184,42 +173,32 @@ int mt7615_mcu_parse_response(struct mt76_dev *mdev, int cmd,
if (seq != rxd->seq)
return -EAGAIN;
switch (cmd) {
case MCU_CMD_PATCH_SEM_CONTROL:
if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
skb_pull(skb, sizeof(*rxd) - 4);
ret = *skb->data;
break;
case MCU_EXT_CMD_GET_TEMP:
} else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
skb_pull(skb, sizeof(*rxd));
ret = le32_to_cpu(*(__le32 *)skb->data);
break;
case MCU_EXT_CMD_RF_REG_ACCESS | MCU_QUERY_PREFIX:
} else if (cmd == MCU_EXT_QUERY(RF_REG_ACCESS)) {
skb_pull(skb, sizeof(*rxd));
ret = le32_to_cpu(*(__le32 *)&skb->data[8]);
break;
case MCU_UNI_CMD_DEV_INFO_UPDATE:
case MCU_UNI_CMD_BSS_INFO_UPDATE:
case MCU_UNI_CMD_STA_REC_UPDATE:
case MCU_UNI_CMD_HIF_CTRL:
case MCU_UNI_CMD_OFFLOAD:
case MCU_UNI_CMD_SUSPEND: {
} else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
cmd == MCU_UNI_CMD(HIF_CTRL) ||
cmd == MCU_UNI_CMD(OFFLOAD) ||
cmd == MCU_UNI_CMD(SUSPEND)) {
struct mt7615_mcu_uni_event *event;
skb_pull(skb, sizeof(*rxd));
event = (struct mt7615_mcu_uni_event *)skb->data;
ret = le32_to_cpu(event->status);
break;
}
case MCU_CMD_REG_READ: {
} else if (cmd == MCU_CE_QUERY(REG_READ)) {
struct mt7615_mcu_reg_event *event;
skb_pull(skb, sizeof(*rxd));
event = (struct mt7615_mcu_reg_event *)skb->data;
ret = (int)le32_to_cpu(event->val);
break;
}
default:
break;
}
return ret;
@ -253,8 +232,7 @@ u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg)
.address = cpu_to_le32(reg),
};
return mt76_mcu_send_msg(&dev->mt76,
MCU_EXT_CMD_RF_REG_ACCESS | MCU_QUERY_PREFIX,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_QUERY(RF_REG_ACCESS),
&req, sizeof(req), true);
}
@ -270,8 +248,8 @@ int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val)
.data = cpu_to_le32(val),
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RF_REG_ACCESS, &req,
sizeof(req), false);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_REG_ACCESS),
&req, sizeof(req), false);
}
void mt7622_trigger_hif_int(struct mt7615_dev *dev, bool en)
@ -658,8 +636,8 @@ mt7615_mcu_muar_config(struct mt7615_dev *dev, struct ieee80211_vif *vif,
if (enable)
ether_addr_copy(req.addr, addr);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_MUAR_UPDATE, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MUAR_UPDATE),
&req, sizeof(req), true);
}
static int
@ -702,7 +680,7 @@ mt7615_mcu_add_dev(struct mt7615_phy *phy, struct ieee80211_vif *vif,
return mt7615_mcu_muar_config(dev, vif, false, enable);
memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_DEV_INFO_UPDATE,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(DEV_INFO_UPDATE),
&data, sizeof(data), true);
}
@ -771,7 +749,7 @@ mt7615_mcu_add_beacon_offload(struct mt7615_dev *dev,
dev_kfree_skb(skb);
out:
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_BCN_OFFLOAD, &req,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(BCN_OFFLOAD), &req,
sizeof(req), true);
}
@ -802,8 +780,8 @@ mt7615_mcu_ctrl_pm_state(struct mt7615_dev *dev, int band, int state)
.band_idx = band,
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_PM_STATE_CTRL, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(PM_STATE_CTRL),
&req, sizeof(req), true);
}
static int
@ -843,7 +821,7 @@ mt7615_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
bss = (struct bss_info_basic *)tlv;
bss->network_type = cpu_to_le32(type);
bss->bmc_tx_wlan_idx = wlan_idx;
bss->bmc_wcid_lo = wlan_idx;
bss->wmm_idx = mvif->mt76.wmm_idx;
bss->active = enable;
@ -944,7 +922,7 @@ mt7615_mcu_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,
mt7615_mcu_bss_ext_tlv(skb, mvif);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD_BSS_INFO_UPDATE, true);
MCU_EXT_CMD(BSS_INFO_UPDATE), true);
}
static int
@ -966,8 +944,8 @@ mt7615_mcu_wtbl_tx_ba(struct mt7615_dev *dev,
mt76_connac_mcu_wtbl_ba_tlv(&dev->mt76, skb, params, enable, true,
NULL, wtbl_hdr);
err = mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE,
true);
err = mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(WTBL_UPDATE), true);
if (err < 0)
return err;
@ -979,7 +957,7 @@ mt7615_mcu_wtbl_tx_ba(struct mt7615_dev *dev,
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, true);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD_STA_REC_UPDATE, true);
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
static int
@ -1001,7 +979,7 @@ mt7615_mcu_wtbl_rx_ba(struct mt7615_dev *dev,
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, false);
err = mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD_STA_REC_UPDATE, true);
MCU_EXT_CMD(STA_REC_UPDATE), true);
if (err < 0 || !enable)
return err;
@ -1014,8 +992,8 @@ mt7615_mcu_wtbl_rx_ba(struct mt7615_dev *dev,
mt76_connac_mcu_wtbl_ba_tlv(&dev->mt76, skb, params, enable, false,
NULL, wtbl_hdr);
return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE,
true);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(WTBL_UPDATE), true);
}
static int
@ -1057,7 +1035,7 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
NULL, wtbl_hdr);
}
cmd = enable ? MCU_EXT_CMD_WTBL_UPDATE : MCU_EXT_CMD_STA_REC_UPDATE;
cmd = enable ? MCU_EXT_CMD(WTBL_UPDATE) : MCU_EXT_CMD(STA_REC_UPDATE);
skb = enable ? wskb : sskb;
err = mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, true);
@ -1068,7 +1046,7 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif,
return err;
}
cmd = enable ? MCU_EXT_CMD_STA_REC_UPDATE : MCU_EXT_CMD_WTBL_UPDATE;
cmd = enable ? MCU_EXT_CMD(STA_REC_UPDATE) : MCU_EXT_CMD(WTBL_UPDATE);
skb = enable ? sskb : wskb;
return mt76_mcu_skb_send_msg(&dev->mt76, skb, cmd, true);
@ -1090,8 +1068,8 @@ mt7615_mcu_wtbl_update_hdr_trans(struct mt7615_dev *dev,
mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, &msta->wcid, NULL,
wtbl_hdr);
return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE,
true);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(WTBL_UPDATE), true);
}
static const struct mt7615_mcu_ops wtbl_update_ops = {
@ -1136,7 +1114,7 @@ mt7615_mcu_sta_ba(struct mt7615_dev *dev,
sta_wtbl, wtbl_hdr);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD_STA_REC_UPDATE, true);
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
static int
@ -1179,7 +1157,7 @@ mt7615_mcu_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable)
{
return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,
MCU_EXT_CMD_STA_REC_UPDATE, false);
MCU_EXT_CMD(STA_REC_UPDATE), false);
}
static int
@ -1191,7 +1169,7 @@ mt7615_mcu_sta_update_hdr_trans(struct mt7615_dev *dev,
return mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76,
vif, &msta->wcid,
MCU_EXT_CMD_STA_REC_UPDATE);
MCU_EXT_CMD(STA_REC_UPDATE));
}
static const struct mt7615_mcu_ops sta_update_ops = {
@ -1285,7 +1263,7 @@ mt7615_mcu_uni_add_beacon_offload(struct mt7615_dev *dev,
dev_kfree_skb(skb);
out:
return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_BSS_INFO_UPDATE,
return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
&req, sizeof(req), true);
}
@ -1314,7 +1292,7 @@ mt7615_mcu_uni_add_sta(struct mt7615_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable)
{
return __mt7615_mcu_add_sta(phy->mt76, vif, sta, enable,
MCU_UNI_CMD_STA_REC_UPDATE, true);
MCU_UNI_CMD(STA_REC_UPDATE), true);
}
static int
@ -1348,7 +1326,7 @@ mt7615_mcu_uni_rx_ba(struct mt7615_dev *dev,
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, false);
err = mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_UNI_CMD_STA_REC_UPDATE, true);
MCU_UNI_CMD(STA_REC_UPDATE), true);
if (err < 0 || !enable)
return err;
@ -1369,7 +1347,7 @@ mt7615_mcu_uni_rx_ba(struct mt7615_dev *dev,
sta_wtbl, wtbl_hdr);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_UNI_CMD_STA_REC_UPDATE, true);
MCU_UNI_CMD(STA_REC_UPDATE), true);
}
static int
@ -1381,7 +1359,7 @@ mt7615_mcu_sta_uni_update_hdr_trans(struct mt7615_dev *dev,
return mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76,
vif, &msta->wcid,
MCU_UNI_CMD_STA_REC_UPDATE);
MCU_UNI_CMD(STA_REC_UPDATE));
}
static const struct mt7615_mcu_ops uni_update_ops = {
@ -1399,7 +1377,7 @@ static const struct mt7615_mcu_ops uni_update_ops = {
int mt7615_mcu_restart(struct mt76_dev *dev)
{
return mt76_mcu_send_msg(dev, MCU_CMD_RESTART_DL_REQ, NULL, 0, true);
return mt76_mcu_send_msg(dev, MCU_CMD(RESTART_DL_REQ), NULL, 0, true);
}
EXPORT_SYMBOL_GPL(mt7615_mcu_restart);
@ -1445,7 +1423,7 @@ static int mt7615_load_patch(struct mt7615_dev *dev, u32 addr, const char *name)
goto out;
}
ret = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD_FW_SCATTER,
ret = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
fw->data + sizeof(*hdr), len);
if (ret) {
dev_err(dev->mt76.dev, "Failed to send firmware to device\n");
@ -1508,7 +1486,7 @@ mt7615_mcu_send_ram_firmware(struct mt7615_dev *dev,
return err;
}
err = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD_FW_SCATTER,
err = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
data + offset, len);
if (err) {
dev_err(dev->mt76.dev, "Failed to send firmware to device\n");
@ -1644,7 +1622,7 @@ static int mt7615_load_firmware(struct mt7615_dev *dev)
if (!mt76_poll_msec(dev, MT_TOP_MISC2, MT_TOP_MISC2_FW_STATE,
FIELD_PREP(MT_TOP_MISC2_FW_STATE,
FW_STATE_CR4_RDY), 500)) {
FW_STATE_RDY), 500)) {
dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
return -EIO;
}
@ -1694,8 +1672,8 @@ int mt7615_mcu_fw_log_2_host(struct mt7615_dev *dev, u8 ctrl)
.ctrl_val = ctrl
};
return mt76_mcu_send_msg(&dev->mt76, MCU_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);
}
static int mt7615_mcu_cal_cache_apply(struct mt7615_dev *dev)
@ -1707,7 +1685,7 @@ static int mt7615_mcu_cal_cache_apply(struct mt7615_dev *dev)
.cache_enable = true
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_CAL_CACHE, &data,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(CAL_CACHE), &data,
sizeof(data), false);
}
@ -1756,7 +1734,7 @@ static int mt7663_load_n9(struct mt7615_dev *dev, const char *name)
goto out;
}
ret = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD_FW_SCATTER,
ret = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
fw->data + offset, len);
if (ret) {
dev_err(dev->mt76.dev, "Failed to send firmware\n");
@ -1977,7 +1955,7 @@ int mt7615_mcu_set_eeprom(struct mt7615_dev *dev)
skb_put_data(skb, eep + offset, eep_len);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD_EFUSE_BUFFER_MODE, true);
MCU_EXT_CMD(EFUSE_BUFFER_MODE), true);
}
int mt7615_mcu_set_wmm(struct mt7615_dev *dev, u8 queue,
@ -2013,8 +1991,8 @@ int mt7615_mcu_set_wmm(struct mt7615_dev *dev, u8 queue,
if (params->cw_max)
req.cw_max = cpu_to_le16(fls(params->cw_max));
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EDCA_UPDATE, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EDCA_UPDATE),
&req, sizeof(req), true);
}
int mt7615_mcu_set_dbdc(struct mt7615_dev *dev)
@ -2072,7 +2050,7 @@ int mt7615_mcu_set_dbdc(struct mt7615_dev *dev)
ADD_DBDC_ENTRY(DBDC_TYPE_MGMT, 1, 1);
out:
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_DBDC_CTRL, &req,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(DBDC_CTRL), &req,
sizeof(req), true);
}
@ -2082,8 +2060,8 @@ int mt7615_mcu_del_wtbl_all(struct mt7615_dev *dev)
.operation = WTBL_RESET_ALL,
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_WTBL_UPDATE, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(WTBL_UPDATE),
&req, sizeof(req), true);
}
int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
@ -2103,8 +2081,8 @@ int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
.val = val,
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_CTRL, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_CTRL),
&req, sizeof(req), true);
}
int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val)
@ -2117,8 +2095,8 @@ int mt7615_mcu_set_fcc5_lpn(struct mt7615_dev *dev, int val)
.min_lpn = cpu_to_le16(val),
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RADAR_TH),
&req, sizeof(req), true);
}
int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev,
@ -2146,8 +2124,8 @@ int mt7615_mcu_set_pulse_th(struct mt7615_dev *dev,
#undef __req_field
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RADAR_TH),
&req, sizeof(req), true);
}
int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index,
@ -2193,8 +2171,8 @@ int mt7615_mcu_set_radar_th(struct mt7615_dev *dev, int index,
#undef __req_field_u32
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RADAR_TH),
&req, sizeof(req), true);
}
int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev)
@ -2225,7 +2203,7 @@ int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev)
req.pattern[i].start_time = cpu_to_le32(ts);
}
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_PATTERN,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_PATTERN),
&req, sizeof(req), false);
}
@ -2394,8 +2372,8 @@ int mt7615_mcu_get_temperature(struct mt7615_dev *dev)
u8 rsv[3];
} req = {};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_GET_TEMP, &req,
sizeof(req), true);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL),
&req, sizeof(req), true);
}
int mt7615_mcu_set_test_param(struct mt7615_dev *dev, u8 param, bool test_mode,
@ -2415,8 +2393,8 @@ int mt7615_mcu_set_test_param(struct mt7615_dev *dev, u8 param, bool test_mode,
.value = cpu_to_le32(val),
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req,
sizeof(req), false);
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL),
&req, sizeof(req), false);
}
int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable)
@ -2434,8 +2412,8 @@ int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable)
};
return mt76_mcu_send_msg(&dev->mt76,
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL, &req,
sizeof(req), true);
MCU_EXT_CMD(TX_POWER_FEATURE_CTRL),
&req, sizeof(req), true);
}
static int mt7615_find_freq_idx(const u16 *freqs, int n_freqs, u16 cur)
@ -2574,7 +2552,7 @@ int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy)
out:
req.center_freq = cpu_to_le16(center_freq);
ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RXDCOC_CAL, &req,
ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RXDCOC_CAL), &req,
sizeof(req), true);
if ((chandef->width == NL80211_CHAN_WIDTH_80P80 ||
@ -2695,8 +2673,8 @@ int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy)
out:
req.center_freq = cpu_to_le16(center_freq);
ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_TXDPD_CAL, &req,
sizeof(req), true);
ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXDPD_CAL),
&req, sizeof(req), true);
if ((chandef->width == NL80211_CHAN_WIDTH_80P80 ||
chandef->width == NL80211_CHAN_WIDTH_160) && !req.is_freq2) {
@ -2724,7 +2702,7 @@ int mt7615_mcu_set_rx_hdr_trans_blacklist(struct mt7615_dev *dev)
.etype = cpu_to_le16(ETH_P_PAE),
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RX_HDR_TRANS,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RX_HDR_TRANS),
&req, sizeof(req), false);
}
@ -2759,13 +2737,13 @@ int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
if (vif->type != NL80211_IFTYPE_STATION)
return 0;
err = mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_BSS_ABORT, &req_hdr,
sizeof(req_hdr), false);
err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),
&req_hdr, sizeof(req_hdr), false);
if (err < 0 || !enable)
return err;
return mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_BSS_CONNECTED, &req,
sizeof(req), false);
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_CONNECTED),
&req, sizeof(req), false);
}
int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
@ -2784,6 +2762,6 @@ int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
phy->roc_grant = false;
return mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_ROC, &req,
sizeof(req), false);
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_ROC),
&req, sizeof(req), false);
}

View file

@ -76,35 +76,6 @@ struct mt7615_uni_txd {
u8 reserved2[4];
} __packed __aligned(4);
/* event table */
enum {
MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
MCU_EVENT_FW_START = 0x01,
MCU_EVENT_GENERIC = 0x01,
MCU_EVENT_ACCESS_REG = 0x02,
MCU_EVENT_MT_PATCH_SEM = 0x04,
MCU_EVENT_REG_ACCESS = 0x05,
MCU_EVENT_SCAN_DONE = 0x0d,
MCU_EVENT_ROC = 0x10,
MCU_EVENT_BSS_ABSENCE = 0x11,
MCU_EVENT_BSS_BEACON_LOSS = 0x13,
MCU_EVENT_CH_PRIVILEGE = 0x18,
MCU_EVENT_SCHED_SCAN_DONE = 0x23,
MCU_EVENT_EXT = 0xed,
MCU_EVENT_RESTART_DL = 0xef,
MCU_EVENT_COREDUMP = 0xf0,
};
/* ext event table */
enum {
MCU_EXT_EVENT_PS_SYNC = 0x5,
MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
MCU_EXT_EVENT_RDD_REPORT = 0x3a,
MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
};
enum {
MT_SKU_CCK_1_2 = 0,
MT_SKU_CCK_55_11,
@ -233,20 +204,6 @@ struct mt7615_mcu_rdd_report {
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
#define MCU_PKT_ID 0xa0
enum {
MCU_Q_QUERY,
MCU_Q_SET,
MCU_Q_RESERVED,
MCU_Q_NA
};
enum {
MCU_S2D_H2N,
MCU_S2D_C2N,
MCU_S2D_H2C,
MCU_S2D_H2CN
};
enum {
MCU_ATE_SET_FREQ_OFFSET = 0xa,
MCU_ATE_SET_TX_POWER_CONTROL = 0x15,
@ -280,21 +237,6 @@ struct mt7615_roc_tlv {
u8 rsv1[8];
} __packed;
enum {
PATCH_NOT_DL_SEM_FAIL = 0x0,
PATCH_IS_DL = 0x1,
PATCH_NOT_DL_SEM_SUCCESS = 0x2,
PATCH_REL_SEM_SUCCESS = 0x3
};
enum {
FW_STATE_INITIAL = 0,
FW_STATE_FW_DOWNLOAD = 1,
FW_STATE_NORMAL_OPERATION = 2,
FW_STATE_NORMAL_TRX = 3,
FW_STATE_CR4_RDY = 7
};
enum {
FW_STATE_PWR_ON = 1,
FW_STATE_N9_RDY = 2,
@ -312,73 +254,4 @@ enum {
__DBDC_TYPE_MAX,
};
struct bss_info_omac {
__le16 tag;
__le16 len;
u8 hw_bss_idx;
u8 omac_idx;
u8 band_idx;
u8 rsv0;
__le32 conn_type;
u32 rsv1;
} __packed;
struct bss_info_basic {
__le16 tag;
__le16 len;
__le32 network_type;
u8 active;
u8 rsv0;
__le16 bcn_interval;
u8 bssid[ETH_ALEN];
u8 wmm_idx;
u8 dtim_period;
u8 bmc_tx_wlan_idx;
u8 cipher; /* not used */
u8 phymode; /* not used */
u8 rsv1[5];
} __packed;
struct bss_info_rf_ch {
__le16 tag;
__le16 len;
u8 pri_ch;
u8 central_ch0;
u8 central_ch1;
u8 bw;
} __packed;
struct bss_info_ext_bss {
__le16 tag;
__le16 len;
__le32 mbss_tsf_offset; /* in unit of us */
u8 rsv[8];
} __packed;
enum {
BSS_INFO_OMAC,
BSS_INFO_BASIC,
BSS_INFO_RF_CH, /* optional, for BT/LTE coex */
BSS_INFO_PM, /* sta only */
BSS_INFO_UAPSD, /* sta only */
BSS_INFO_ROAM_DETECTION, /* obsoleted */
BSS_INFO_LQ_RM, /* obsoleted */
BSS_INFO_EXT_BSS,
BSS_INFO_BMC_INFO, /* for bmc rate control in CR4 */
BSS_INFO_SYNC_MODE, /* obsoleted */
BSS_INFO_RA,
BSS_INFO_MAX_NUM
};
enum {
CH_SWITCH_NORMAL = 0,
CH_SWITCH_SCAN = 3,
CH_SWITCH_MCC = 4,
CH_SWITCH_DFS = 5,
CH_SWITCH_BACKGROUND_SCAN_START = 6,
CH_SWITCH_BACKGROUND_SCAN_RUNNING = 7,
CH_SWITCH_BACKGROUND_SCAN_STOP = 8,
CH_SWITCH_SCAN_BYPASS_DPD = 9
};
#endif

View file

@ -135,6 +135,7 @@ static void mt7615_irq_tasklet(struct tasklet_struct *t)
if (is_mt7663(&dev->mt76)) {
mcu_int = mt76_rr(dev, MT_MCU2HOST_INT_STATUS);
mcu_int &= MT7663_MCU_CMD_ERROR_MASK;
mt76_wr(dev, MT_MCU2HOST_INT_STATUS, mcu_int);
} else {
mcu_int = mt76_rr(dev, MT_MCU_CMD);
mcu_int &= MT_MCU_CMD_ERROR_MASK;

View file

@ -28,8 +28,6 @@ static void mt7615_pci_init_work(struct work_struct *work)
return;
mt7615_init_work(dev);
if (dev->dbdc_support)
mt7615_register_ext_phy(dev);
}
static int mt7615_init_hardware(struct mt7615_dev *dev)
@ -160,6 +158,12 @@ int mt7615_register_device(struct mt7615_dev *dev)
mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
if (dev->dbdc_support) {
ret = mt7615_register_ext_phy(dev);
if (ret)
return ret;
}
return mt7615_init_debugfs(dev);
}

View file

@ -91,7 +91,7 @@ mt7615_tm_set_tx_power(struct mt7615_phy *phy)
}
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD_SET_TX_POWER_CTRL, false);
MCU_EXT_CMD(SET_TX_POWER_CTRL), false);
}
static void
@ -185,36 +185,35 @@ mt7615_tm_set_tx_antenna(struct mt7615_phy *phy, bool en)
for (i = 0; i < 4; i++) {
mt76_rmw_field(dev, MT_WF_PHY_RFINTF3_0(i),
MT_WF_PHY_RFINTF3_0_ANT,
(td->tx_antenna_mask & BIT(i)) ? 0 : 0xa);
(mask & BIT(i)) ? 0 : 0xa);
}
/* 2.4 GHz band */
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(3), MT_ANT_SWITCH_CON_MODE(0),
(td->tx_antenna_mask & BIT(0)) ? 0x8 : 0x1b);
(mask & BIT(0)) ? 0x8 : 0x1b);
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(4), MT_ANT_SWITCH_CON_MODE(2),
(td->tx_antenna_mask & BIT(1)) ? 0xe : 0x1b);
(mask & BIT(1)) ? 0xe : 0x1b);
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(6), MT_ANT_SWITCH_CON_MODE1(0),
(td->tx_antenna_mask & BIT(2)) ? 0x0 : 0xf);
(mask & BIT(2)) ? 0x0 : 0xf);
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(7), MT_ANT_SWITCH_CON_MODE1(2),
(td->tx_antenna_mask & BIT(3)) ? 0x6 : 0xf);
(mask & BIT(3)) ? 0x6 : 0xf);
/* 5 GHz band */
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(4), MT_ANT_SWITCH_CON_MODE(1),
(td->tx_antenna_mask & BIT(0)) ? 0xd : 0x1b);
(mask & BIT(0)) ? 0xd : 0x1b);
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(2), MT_ANT_SWITCH_CON_MODE(3),
(td->tx_antenna_mask & BIT(1)) ? 0x13 : 0x1b);
(mask & BIT(1)) ? 0x13 : 0x1b);
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(7), MT_ANT_SWITCH_CON_MODE1(1),
(td->tx_antenna_mask & BIT(2)) ? 0x5 : 0xf);
(mask & BIT(2)) ? 0x5 : 0xf);
mt76_rmw_field(dev, MT_ANT_SWITCH_CON(8), MT_ANT_SWITCH_CON_MODE1(3),
(td->tx_antenna_mask & BIT(3)) ? 0xb : 0xf);
(mask & BIT(3)) ? 0xb : 0xf);
for (i = 0; i < 4; i++) {
u32 val;
val = mt7615_rf_rr(dev, i, 0x48);
val &= ~(0x3ff << 20);
if (td->tx_antenna_mask & BIT(i))
if (mask & BIT(i))
val |= 3 << 20;
else
val |= (2 << 28) | (2 << 26) | (8 << 20);
@ -229,7 +228,7 @@ mt7615_tm_set_tx_frames(struct mt7615_phy *phy, bool en)
struct ieee80211_tx_info *info;
struct sk_buff *skb = phy->mt76->test.tx_skb;
mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
mt7615_tm_set_tx_antenna(phy, en);
mt7615_tm_set_rx_enable(dev, !en);
if (!en || !skb)

View file

@ -21,7 +21,7 @@ mt7663u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
int ret, ep, len, pad;
mt7615_mcu_fill_msg(dev, skb, cmd, seq);
if (cmd != MCU_CMD_FW_SCATTER)
if (cmd != MCU_CMD(FW_SCATTER))
ep = MT_EP_OUT_INBAND_CMD;
else
ep = MT_EP_OUT_AC_BE;

View file

@ -13,8 +13,8 @@ int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
.addr = cpu_to_le32(addr),
};
return mt76_mcu_send_msg(dev, MCU_CMD_FW_START_REQ, &req, sizeof(req),
true);
return mt76_mcu_send_msg(dev, MCU_CMD(FW_START_REQ), &req,
sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);
@ -27,8 +27,8 @@ int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)
.op = cpu_to_le32(op),
};
return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_SEM_CONTROL, &req,
sizeof(req), true);
return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_SEM_CONTROL),
&req, sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);
@ -41,8 +41,8 @@ int mt76_connac_mcu_start_patch(struct mt76_dev *dev)
.check_crc = 0,
};
return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_FINISH_REQ, &req,
sizeof(req), true);
return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_FINISH_REQ),
&req, sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch);
@ -64,9 +64,9 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
if (is_mt7921(dev) &&
(req.addr == cpu_to_le32(MCU_PATCH_ADDRESS) || addr == 0x900000))
cmd = MCU_CMD_PATCH_START_REQ;
cmd = MCU_CMD(PATCH_START_REQ);
else
cmd = MCU_CMD_TARGET_ADDRESS_LEN_REQ;
cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
return mt76_mcu_send_msg(dev, cmd, &req, sizeof(req), true);
}
@ -160,7 +160,8 @@ int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
return mt76_mcu_skb_send_msg(dev, skb, MCU_CMD_SET_CHAN_DOMAIN, false);
return mt76_mcu_skb_send_msg(dev, skb, MCU_CE_CMD(SET_CHAN_DOMAIN),
false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
@ -176,7 +177,7 @@ int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
.band = band,
};
return mt76_mcu_send_msg(dev, MCU_EXT_CMD_MAC_INIT_CTRL, &req_mac,
return mt76_mcu_send_msg(dev, MCU_EXT_CMD(MAC_INIT_CTRL), &req_mac,
sizeof(req_mac), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
@ -198,8 +199,8 @@ int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
if (vif->type != NL80211_IFTYPE_STATION)
return -EOPNOTSUPP;
return mt76_mcu_send_msg(dev, MCU_CMD_SET_PS_PROFILE, &req,
sizeof(req), false);
return mt76_mcu_send_msg(dev, MCU_CE_CMD(SET_PS_PROFILE),
&req, sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
@ -218,7 +219,7 @@ int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band)
.pkt_thresh = cpu_to_le32(0x2),
};
return mt76_mcu_send_msg(dev, MCU_EXT_CMD_PROTECT_CTRL, &req,
return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PROTECT_CTRL), &req,
sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
@ -257,11 +258,8 @@ mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
if (sta_hdr) {
u16 size = le16_to_cpu(sta_hdr->len);
sta_hdr->len = cpu_to_le16(size + len);
}
if (sta_hdr)
le16_add_cpu(&sta_hdr->len, len);
return ptlv;
}
@ -1071,7 +1069,7 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
cmd = enable ? MCU_UNI_CMD_DEV_INFO_UPDATE : MCU_UNI_CMD_BSS_INFO_UPDATE;
cmd = enable ? MCU_UNI_CMD(DEV_INFO_UPDATE) : MCU_UNI_CMD(BSS_INFO_UPDATE);
data = enable ? (void *)&dev_req : (void *)&basic_req;
len = enable ? sizeof(dev_req) : sizeof(basic_req);
@ -1079,7 +1077,7 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
if (err < 0)
return err;
cmd = enable ? MCU_UNI_CMD_BSS_INFO_UPDATE : MCU_UNI_CMD_DEV_INFO_UPDATE;
cmd = enable ? MCU_UNI_CMD(BSS_INFO_UPDATE) : MCU_UNI_CMD(DEV_INFO_UPDATE);
data = enable ? (void *)&basic_req : (void *)&dev_req;
len = enable ? sizeof(basic_req) : sizeof(dev_req);
@ -1131,7 +1129,8 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
wtbl_hdr);
ret = mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE, true);
ret = mt76_mcu_skb_send_msg(dev, skb,
MCU_UNI_CMD(STA_REC_UPDATE), true);
if (ret)
return ret;
@ -1141,8 +1140,8 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE,
true);
return mt76_mcu_skb_send_msg(dev, skb,
MCU_UNI_CMD(STA_REC_UPDATE), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
@ -1179,7 +1178,7 @@ mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
if (ht_cap->ht_supported)
mode |= PHY_MODE_GN;
if (he_cap->has_he)
if (he_cap && he_cap->has_he)
mode |= PHY_MODE_AX_24G;
} else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
mode |= PHY_MODE_A;
@ -1190,12 +1189,8 @@ mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
if (vht_cap->vht_supported)
mode |= PHY_MODE_AC;
if (he_cap->has_he) {
if (band == NL80211_BAND_6GHZ)
mode |= PHY_MODE_AX_6G;
else
mode |= PHY_MODE_AX_5G;
}
if (he_cap && he_cap->has_he && band == NL80211_BAND_5GHZ)
mode |= PHY_MODE_AX_5G;
}
return mode;
@ -1318,7 +1313,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
basic_req.basic.hw_bss_idx = idx;
if (band == NL80211_BAND_6GHZ)
basic_req.basic.phymode_ext = BIT(0);
basic_req.basic.phymode_ext = PHY_MODE_AX_6G;
basic_phy = mt76_connac_get_phy_mode_v2(phy, vif, band, NULL);
basic_req.basic.nonht_basic_phy = cpu_to_le16(basic_phy);
@ -1352,7 +1347,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
basic_req.basic.conn_state = !enable;
err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &basic_req,
err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &basic_req,
sizeof(basic_req), true);
if (err < 0)
return err;
@ -1390,7 +1385,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
(struct tlv *)&he_req.he);
err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE,
err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE),
&he_req, sizeof(he_req), true);
if (err < 0)
return err;
@ -1428,7 +1423,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
rlm_req.rlm.sco = 3; /* SCB */
return mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &rlm_req,
return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req,
sizeof(rlm_req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
@ -1522,7 +1517,8 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
req->scan_func |= SCAN_FUNC_RANDOM_MAC;
}
err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_START_HW_SCAN, false);
err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(START_HW_SCAN),
false);
if (err < 0)
clear_bit(MT76_HW_SCANNING, &phy->state);
@ -1550,8 +1546,8 @@ int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
ieee80211_scan_completed(phy->hw, &info);
}
return mt76_mcu_send_msg(phy->dev, MCU_CMD_CANCEL_HW_SCAN, &req,
sizeof(req), false);
return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(CANCEL_HW_SCAN),
&req, sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
@ -1637,7 +1633,8 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
}
return mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_SCHED_SCAN_REQ, false);
return mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(SCHED_SCAN_REQ),
false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
@ -1657,8 +1654,8 @@ int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
else
clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
return mt76_mcu_send_msg(phy->dev, MCU_CMD_SCHED_SCAN_ENABLE, &req,
sizeof(req), false);
return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SCHED_SCAN_ENABLE),
&req, sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
@ -1670,8 +1667,8 @@ int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
memcpy(req.data, "assert", 7);
return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
false);
return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
&req, sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
@ -1683,8 +1680,8 @@ int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
false);
return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
&req, sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
@ -1786,8 +1783,8 @@ int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy)
struct sk_buff *skb;
int ret, i;
ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CMD_GET_NIC_CAPAB, NULL,
0, true, &skb);
ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CE_CMD(GET_NIC_CAPAB),
NULL, 0, true, &skb);
if (ret)
return ret;
@ -1885,30 +1882,6 @@ mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku,
}
}
static s8 mt76_connac_get_sar_power(struct mt76_phy *phy,
struct ieee80211_channel *chan,
s8 target_power)
{
const struct cfg80211_sar_capa *capa = phy->hw->wiphy->sar_capa;
struct mt76_freq_range_power *frp = phy->frp;
int freq, i;
if (!capa || !frp)
return target_power;
freq = ieee80211_channel_to_frequency(chan->hw_value, chan->band);
for (i = 0 ; i < capa->num_freq_ranges; i++) {
if (frp[i].range &&
freq >= frp[i].range->start_freq &&
freq < frp[i].range->end_freq) {
target_power = min_t(s8, frp[i].power, target_power);
break;
}
}
return target_power;
}
static s8 mt76_connac_get_ch_power(struct mt76_phy *phy,
struct ieee80211_channel *chan,
s8 target_power)
@ -2008,12 +1981,12 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
}
batch_size = DIV_ROUND_UP(n_chan, batch_len);
if (!phy->cap.has_5ghz)
last_ch = chan_list_2ghz[n_chan - 1];
else if (phy->cap.has_6ghz)
last_ch = chan_list_6ghz[n_chan - 1];
if (phy->cap.has_6ghz)
last_ch = chan_list_6ghz[ARRAY_SIZE(chan_list_6ghz) - 1];
else if (phy->cap.has_5ghz)
last_ch = chan_list_5ghz[ARRAY_SIZE(chan_list_5ghz) - 1];
else
last_ch = chan_list_5ghz[n_chan - 1];
last_ch = chan_list_2ghz[ARRAY_SIZE(chan_list_2ghz) - 1];
for (i = 0; i < batch_size; i++) {
struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {};
@ -2053,8 +2026,7 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
reg_power = mt76_connac_get_ch_power(phy, &chan,
tx_power);
sar_power = mt76_connac_get_sar_power(phy, &chan,
reg_power);
sar_power = mt76_get_sar_power(phy, &chan, reg_power);
mt76_get_rate_power_limits(phy, &chan, &limits,
sar_power);
@ -2070,7 +2042,8 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv));
err = mt76_mcu_skb_send_msg(dev, skb,
MCU_CMD_SET_RATE_TX_POWER, false);
MCU_CE_CMD(SET_RATE_TX_POWER),
false);
if (err < 0)
return err;
}
@ -2143,7 +2116,7 @@ int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
}
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_OFFLOAD, true);
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter);
@ -2162,8 +2135,8 @@ int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
.bss_idx = mvif->idx,
};
return mt76_mcu_send_msg(phy->dev, MCU_CMD_SET_P2P_OPPPS, &req,
sizeof(req), false);
return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SET_P2P_OPPPS),
&req, sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_p2p_oppps);
@ -2249,7 +2222,8 @@ int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
return mt76_mcu_skb_send_msg(phy->dev, skb, MCU_UNI_CMD_OFFLOAD, true);
return mt76_mcu_skb_send_msg(phy->dev, skb,
MCU_UNI_CMD(OFFLOAD), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
@ -2275,8 +2249,8 @@ mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
},
};
return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
true);
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
sizeof(req), true);
}
static int
@ -2301,8 +2275,8 @@ mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
},
};
return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
true);
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
sizeof(req), true);
}
static int
@ -2331,8 +2305,8 @@ mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
},
};
return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
true);
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
sizeof(req), true);
}
static int
@ -2366,7 +2340,7 @@ mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_SUSPEND, true);
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SUSPEND), true);
}
static int
@ -2418,8 +2392,8 @@ mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
else if (mt76_is_sdio(dev))
req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
true);
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
sizeof(req), true);
}
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
@ -2452,8 +2426,8 @@ int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
else if (mt76_is_sdio(dev))
req.hdr.hif_type = 0;
return mt76_mcu_send_msg(dev, MCU_UNI_CMD_HIF_CTRL, &req, sizeof(req),
true);
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req,
sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
@ -2461,7 +2435,7 @@ void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif)
{
struct mt76_phy *phy = priv;
bool suspend = test_bit(MT76_STATE_SUSPEND, &phy->state);
bool suspend = !test_bit(MT76_STATE_RUNNING, &phy->state);
struct ieee80211_hw *hw = phy->hw;
struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
int i;
@ -2488,8 +2462,8 @@ u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset)
.addr = cpu_to_le32(offset),
};
return mt76_mcu_send_msg(dev, MCU_CMD_REG_READ, &req, sizeof(req),
true);
return mt76_mcu_send_msg(dev, MCU_CE_QUERY(REG_READ), &req,
sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_rr);
@ -2503,7 +2477,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val)
.val = cpu_to_le32(val),
};
mt76_mcu_send_msg(dev, MCU_CMD_REG_WRITE, &req, sizeof(req), false);
mt76_mcu_send_msg(dev, MCU_CE_CMD(REG_WRITE), &req,
sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr);

View file

@ -11,6 +11,76 @@ struct tlv {
__le16 len;
} __packed;
struct bss_info_omac {
__le16 tag;
__le16 len;
u8 hw_bss_idx;
u8 omac_idx;
u8 band_idx;
u8 rsv0;
__le32 conn_type;
u32 rsv1;
} __packed;
struct bss_info_basic {
__le16 tag;
__le16 len;
__le32 network_type;
u8 active;
u8 rsv0;
__le16 bcn_interval;
u8 bssid[ETH_ALEN];
u8 wmm_idx;
u8 dtim_period;
u8 bmc_wcid_lo;
u8 cipher;
u8 phy_mode;
u8 max_bssid; /* max BSSID. range: 1 ~ 8, 0: MBSSID disabled */
u8 non_tx_bssid;/* non-transmitted BSSID, 0: transmitted BSSID */
u8 bmc_wcid_hi; /* high Byte and version */
u8 rsv[2];
} __packed;
struct bss_info_rf_ch {
__le16 tag;
__le16 len;
u8 pri_ch;
u8 center_ch0;
u8 center_ch1;
u8 bw;
u8 he_ru26_block; /* 1: don't send HETB in RU26, 0: allow */
u8 he_all_disable; /* 1: disallow all HETB, 0: allow */
u8 rsv[2];
} __packed;
struct bss_info_ext_bss {
__le16 tag;
__le16 len;
__le32 mbss_tsf_offset; /* in unit of us */
u8 rsv[8];
} __packed;
enum {
BSS_INFO_OMAC,
BSS_INFO_BASIC,
BSS_INFO_RF_CH, /* optional, for BT/LTE coex */
BSS_INFO_PM, /* sta only */
BSS_INFO_UAPSD, /* sta only */
BSS_INFO_ROAM_DETECT, /* obsoleted */
BSS_INFO_LQ_RM, /* obsoleted */
BSS_INFO_EXT_BSS,
BSS_INFO_BMC_RATE, /* for bmc rate control in CR4 */
BSS_INFO_SYNC_MODE, /* obsoleted */
BSS_INFO_RA,
BSS_INFO_HW_AMSDU,
BSS_INFO_BSS_COLOR,
BSS_INFO_HE_BASIC,
BSS_INFO_PROTECT_INFO,
BSS_INFO_OFFLOAD,
BSS_INFO_11V_MBSSID,
BSS_INFO_MAX_NUM
};
/* sta_rec */
struct sta_ntlv_hdr {
@ -54,7 +124,7 @@ struct sta_rec_vht {
__le32 vht_cap;
__le16 vht_rx_mcs_map;
__le16 vht_tx_mcs_map;
/* mt7921 */
/* mt7915 - mt7921 */
u8 rts_bw_sig;
u8 rsv[3];
} __packed;
@ -152,6 +222,191 @@ struct sta_rec_he_6g_capa {
u8 rsv[2];
} __packed;
struct sec_key {
u8 cipher_id;
u8 cipher_len;
u8 key_id;
u8 key_len;
u8 key[32];
} __packed;
struct sta_rec_sec {
__le16 tag;
__le16 len;
u8 add;
u8 n_cipher;
u8 rsv[2];
struct sec_key key[2];
} __packed;
struct sta_rec_bf {
__le16 tag;
__le16 len;
__le16 pfmu; /* 0xffff: no access right for PFMU */
bool su_mu; /* 0: SU, 1: MU */
u8 bf_cap; /* 0: iBF, 1: eBF */
u8 sounding_phy; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT */
u8 ndpa_rate;
u8 ndp_rate;
u8 rept_poll_rate;
u8 tx_mode; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT ... */
u8 ncol;
u8 nrow;
u8 bw; /* 0: 20M, 1: 40M, 2: 80M, 3: 160M */
u8 mem_total;
u8 mem_20m;
struct {
u8 row;
u8 col: 6, row_msb: 2;
} mem[4];
__le16 smart_ant;
u8 se_idx;
u8 auto_sounding; /* b7: low traffic indicator
* b6: Stop sounding for this entry
* b5 ~ b0: postpone sounding
*/
u8 ibf_timeout;
u8 ibf_dbw;
u8 ibf_ncol;
u8 ibf_nrow;
u8 nrow_bw160;
u8 ncol_bw160;
u8 ru_start_idx;
u8 ru_end_idx;
bool trigger_su;
bool trigger_mu;
bool ng16_su;
bool ng16_mu;
bool codebook42_su;
bool codebook75_mu;
u8 he_ltf;
u8 rsv[3];
} __packed;
struct sta_rec_bfee {
__le16 tag;
__le16 len;
bool fb_identity_matrix; /* 1: feedback identity matrix */
bool ignore_feedback; /* 1: ignore */
u8 rsv[2];
} __packed;
struct sta_rec_muru {
__le16 tag;
__le16 len;
struct {
bool ofdma_dl_en;
bool ofdma_ul_en;
bool mimo_dl_en;
bool mimo_ul_en;
u8 rsv[4];
} cfg;
struct {
u8 punc_pream_rx;
bool he_20m_in_40m_2g;
bool he_20m_in_160m;
bool he_80m_in_160m;
bool lt16_sigb;
bool rx_su_comp_sigb;
bool rx_su_non_comp_sigb;
u8 rsv;
} ofdma_dl;
struct {
u8 t_frame_dur;
u8 mu_cascading;
u8 uo_ra;
u8 he_2x996_tone;
u8 rx_t_frame_11ac;
u8 rsv[3];
} ofdma_ul;
struct {
bool vht_mu_bfee;
bool partial_bw_dl_mimo;
u8 rsv[2];
} mimo_dl;
struct {
bool full_ul_mimo;
bool partial_ul_mimo;
u8 rsv[2];
} mimo_ul;
} __packed;
struct sta_phy {
u8 type;
u8 flag;
u8 stbc;
u8 sgi;
u8 bw;
u8 ldpc;
u8 mcs;
u8 nss;
u8 he_ltf;
};
struct sta_rec_ra {
__le16 tag;
__le16 len;
u8 valid;
u8 auto_rate;
u8 phy_mode;
u8 channel;
u8 bw;
u8 disable_cck;
u8 ht_mcs32;
u8 ht_gf;
u8 ht_mcs[4];
u8 mmps_mode;
u8 gband_256;
u8 af;
u8 auth_wapi_mode;
u8 rate_len;
u8 supp_mode;
u8 supp_cck_rate;
u8 supp_ofdm_rate;
__le32 supp_ht_mcs;
__le16 supp_vht_mcs[4];
u8 op_mode;
u8 op_vht_chan_width;
u8 op_vht_rx_nss;
u8 op_vht_rx_nss_type;
__le32 sta_cap;
struct sta_phy phy;
} __packed;
struct sta_rec_ra_fixed {
__le16 tag;
__le16 len;
__le32 field;
u8 op_mode;
u8 op_vht_chan_width;
u8 op_vht_rx_nss;
u8 op_vht_rx_nss_type;
struct sta_phy phy;
u8 spe_en;
u8 short_preamble;
u8 is_5g;
u8 mmps_mode;
} __packed;
/* wtbl_rec */
struct wtbl_req_hdr {
@ -234,6 +489,7 @@ struct wtbl_ba {
__le16 sn;
u8 ba_en;
u8 ba_winsize_idx;
/* originator & recipient */
__le16 ba_winsize;
/* recipient only */
u8 peer_addr[ETH_ALEN];
@ -304,12 +560,17 @@ struct wtbl_raw {
#define MT76_CONNAC_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
sizeof(struct sta_rec_basic) + \
sizeof(struct sta_rec_bf) + \
sizeof(struct sta_rec_ht) + \
sizeof(struct sta_rec_he) + \
sizeof(struct sta_rec_ba) + \
sizeof(struct sta_rec_vht) + \
sizeof(struct sta_rec_uapsd) + \
sizeof(struct sta_rec_amsdu) + \
sizeof(struct sta_rec_muru) + \
sizeof(struct sta_rec_bfee) + \
sizeof(struct sta_rec_ra) + \
sizeof(struct sta_rec_ra_fixed) + \
sizeof(struct sta_rec_he_6g_capa) + \
sizeof(struct tlv) + \
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
@ -423,7 +684,8 @@ enum {
#define PHY_MODE_AC BIT(5)
#define PHY_MODE_AX_24G BIT(6)
#define PHY_MODE_AX_5G BIT(7)
#define PHY_MODE_AX_6G BIT(8)
#define PHY_MODE_AX_6G BIT(0) /* phymode_ext */
#define MODE_CCK BIT(0)
#define MODE_OFDM BIT(1)
@ -431,6 +693,21 @@ enum {
#define MODE_VHT BIT(3)
#define MODE_HE BIT(4)
#define STA_CAP_WMM BIT(0)
#define STA_CAP_SGI_20 BIT(4)
#define STA_CAP_SGI_40 BIT(5)
#define STA_CAP_TX_STBC BIT(6)
#define STA_CAP_RX_STBC BIT(7)
#define STA_CAP_VHT_SGI_80 BIT(16)
#define STA_CAP_VHT_SGI_160 BIT(17)
#define STA_CAP_VHT_TX_STBC BIT(18)
#define STA_CAP_VHT_RX_STBC BIT(19)
#define STA_CAP_VHT_LDPC BIT(23)
#define STA_CAP_LDPC BIT(24)
#define STA_CAP_HT BIT(26)
#define STA_CAP_VHT BIT(27)
#define STA_CAP_HE BIT(28)
enum {
PHY_TYPE_HR_DSSS_INDEX = 0,
PHY_TYPE_ERP_INDEX,
@ -489,6 +766,121 @@ enum {
DEV_INFO_MAX_NUM
};
/* event table */
enum {
MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
MCU_EVENT_FW_START = 0x01,
MCU_EVENT_GENERIC = 0x01,
MCU_EVENT_ACCESS_REG = 0x02,
MCU_EVENT_MT_PATCH_SEM = 0x04,
MCU_EVENT_REG_ACCESS = 0x05,
MCU_EVENT_LP_INFO = 0x07,
MCU_EVENT_SCAN_DONE = 0x0d,
MCU_EVENT_TX_DONE = 0x0f,
MCU_EVENT_ROC = 0x10,
MCU_EVENT_BSS_ABSENCE = 0x11,
MCU_EVENT_BSS_BEACON_LOSS = 0x13,
MCU_EVENT_CH_PRIVILEGE = 0x18,
MCU_EVENT_SCHED_SCAN_DONE = 0x23,
MCU_EVENT_DBG_MSG = 0x27,
MCU_EVENT_TXPWR = 0xd0,
MCU_EVENT_EXT = 0xed,
MCU_EVENT_RESTART_DL = 0xef,
MCU_EVENT_COREDUMP = 0xf0,
};
/* ext event table */
enum {
MCU_EXT_EVENT_PS_SYNC = 0x5,
MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
MCU_EXT_EVENT_RDD_REPORT = 0x3a,
MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
MCU_EXT_EVENT_MURU_CTRL = 0x9f,
};
enum {
MCU_Q_QUERY,
MCU_Q_SET,
MCU_Q_RESERVED,
MCU_Q_NA
};
enum {
MCU_S2D_H2N,
MCU_S2D_C2N,
MCU_S2D_H2C,
MCU_S2D_H2CN
};
enum {
PATCH_NOT_DL_SEM_FAIL,
PATCH_IS_DL,
PATCH_NOT_DL_SEM_SUCCESS,
PATCH_REL_SEM_SUCCESS
};
enum {
FW_STATE_INITIAL,
FW_STATE_FW_DOWNLOAD,
FW_STATE_NORMAL_OPERATION,
FW_STATE_NORMAL_TRX,
FW_STATE_RDY = 7
};
enum {
CH_SWITCH_NORMAL = 0,
CH_SWITCH_SCAN = 3,
CH_SWITCH_MCC = 4,
CH_SWITCH_DFS = 5,
CH_SWITCH_BACKGROUND_SCAN_START = 6,
CH_SWITCH_BACKGROUND_SCAN_RUNNING = 7,
CH_SWITCH_BACKGROUND_SCAN_STOP = 8,
CH_SWITCH_SCAN_BYPASS_DPD = 9
};
enum {
THERMAL_SENSOR_TEMP_QUERY,
THERMAL_SENSOR_MANUAL_CTRL,
THERMAL_SENSOR_INFO_QUERY,
THERMAL_SENSOR_TASK_CTRL,
};
enum mcu_cipher_type {
MCU_CIPHER_NONE = 0,
MCU_CIPHER_WEP40,
MCU_CIPHER_WEP104,
MCU_CIPHER_WEP128,
MCU_CIPHER_TKIP,
MCU_CIPHER_AES_CCMP,
MCU_CIPHER_CCMP_256,
MCU_CIPHER_GCMP,
MCU_CIPHER_GCMP_256,
MCU_CIPHER_WAPI,
MCU_CIPHER_BIP_CMAC_128,
};
enum {
EE_MODE_EFUSE,
EE_MODE_BUFFER,
};
enum {
EE_FORMAT_BIN,
EE_FORMAT_WHOLE,
EE_FORMAT_MULTIPLE,
};
enum {
MCU_PHY_STATE_TX_RATE,
MCU_PHY_STATE_RX_RATE,
MCU_PHY_STATE_RSSI,
MCU_PHY_STATE_CONTENTION_RX_RATE,
MCU_PHY_STATE_OFDMLQ_CNINFO,
};
#define MCU_CMD_ACK BIT(0)
#define MCU_CMD_UNI BIT(1)
#define MCU_CMD_QUERY BIT(2)
@ -496,29 +888,51 @@ enum {
#define MCU_CMD_UNI_EXT_ACK (MCU_CMD_ACK | MCU_CMD_UNI | \
MCU_CMD_QUERY)
#define MCU_FW_PREFIX BIT(31)
#define MCU_UNI_PREFIX BIT(30)
#define MCU_CE_PREFIX BIT(29)
#define MCU_QUERY_PREFIX BIT(28)
#define MCU_CMD_MASK ~(MCU_FW_PREFIX | MCU_UNI_PREFIX | \
MCU_CE_PREFIX | MCU_QUERY_PREFIX)
#define __MCU_CMD_FIELD_ID GENMASK(7, 0)
#define __MCU_CMD_FIELD_EXT_ID GENMASK(15, 8)
#define __MCU_CMD_FIELD_QUERY BIT(16)
#define __MCU_CMD_FIELD_UNI BIT(17)
#define __MCU_CMD_FIELD_CE BIT(18)
#define __MCU_CMD_FIELD_WA BIT(19)
#define MCU_QUERY_MASK BIT(16)
#define MCU_CMD(_t) FIELD_PREP(__MCU_CMD_FIELD_ID, \
MCU_CMD_##_t)
#define MCU_EXT_CMD(_t) (MCU_CMD(EXT_CID) | \
FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \
MCU_EXT_CMD_##_t))
#define MCU_EXT_QUERY(_t) (MCU_EXT_CMD(_t) | __MCU_CMD_FIELD_QUERY)
#define MCU_UNI_CMD(_t) (__MCU_CMD_FIELD_UNI | \
FIELD_PREP(__MCU_CMD_FIELD_ID, \
MCU_UNI_CMD_##_t))
#define MCU_CE_CMD(_t) (__MCU_CMD_FIELD_CE | \
FIELD_PREP(__MCU_CMD_FIELD_ID, \
MCU_CE_CMD_##_t))
#define MCU_CE_QUERY(_t) (MCU_CE_CMD(_t) | __MCU_CMD_FIELD_QUERY)
#define MCU_WA_CMD(_t) (MCU_CMD(_t) | __MCU_CMD_FIELD_WA)
#define MCU_WA_EXT_CMD(_t) (MCU_EXT_CMD(_t) | __MCU_CMD_FIELD_WA)
#define MCU_WA_PARAM_CMD(_t) (MCU_WA_CMD(WA_PARAM) | \
FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \
MCU_WA_PARAM_CMD_##_t))
enum {
MCU_EXT_CMD_EFUSE_ACCESS = 0x01,
MCU_EXT_CMD_RF_REG_ACCESS = 0x02,
MCU_EXT_CMD_RF_TEST = 0x04,
MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11,
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
MCU_EXT_CMD_TXBF_ACTION = 0x1e,
MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
MCU_EXT_CMD_THERMAL_PROT = 0x23,
MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
MCU_EXT_CMD_GET_TEMP = 0x2c,
MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
MCU_EXT_CMD_ATE_CTRL = 0x3d,
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
@ -527,59 +941,74 @@ enum {
MCU_EXT_CMD_RX_HDR_TRANS = 0x47,
MCU_EXT_CMD_MUAR_UPDATE = 0x48,
MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a,
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f,
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
MCU_EXT_CMD_RXDCOC_CAL = 0x59,
MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
MCU_EXT_CMD_TXDPD_CAL = 0x60,
MCU_EXT_CMD_CAL_CACHE = 0x67,
MCU_EXT_CMD_SET_RDD_TH = 0x7c,
MCU_EXT_CMD_SET_RADAR_TH = 0x7c,
MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
MCU_EXT_CMD_SCS_CTRL = 0x82,
MCU_EXT_CMD_TWT_AGRT_UPDATE = 0x94,
MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
MCU_EXT_CMD_SET_RDD_TH = 0x9d,
MCU_EXT_CMD_MURU_CTRL = 0x9f,
MCU_EXT_CMD_SET_SPR = 0xa8,
MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
};
enum {
MCU_UNI_CMD_DEV_INFO_UPDATE = MCU_UNI_PREFIX | 0x01,
MCU_UNI_CMD_BSS_INFO_UPDATE = MCU_UNI_PREFIX | 0x02,
MCU_UNI_CMD_STA_REC_UPDATE = MCU_UNI_PREFIX | 0x03,
MCU_UNI_CMD_SUSPEND = MCU_UNI_PREFIX | 0x05,
MCU_UNI_CMD_OFFLOAD = MCU_UNI_PREFIX | 0x06,
MCU_UNI_CMD_HIF_CTRL = MCU_UNI_PREFIX | 0x07,
MCU_UNI_CMD_DEV_INFO_UPDATE = 0x01,
MCU_UNI_CMD_BSS_INFO_UPDATE = 0x02,
MCU_UNI_CMD_STA_REC_UPDATE = 0x03,
MCU_UNI_CMD_SUSPEND = 0x05,
MCU_UNI_CMD_OFFLOAD = 0x06,
MCU_UNI_CMD_HIF_CTRL = 0x07,
};
enum {
MCU_CMD_TARGET_ADDRESS_LEN_REQ = MCU_FW_PREFIX | 0x01,
MCU_CMD_FW_START_REQ = MCU_FW_PREFIX | 0x02,
MCU_CMD_TARGET_ADDRESS_LEN_REQ = 0x01,
MCU_CMD_FW_START_REQ = 0x02,
MCU_CMD_INIT_ACCESS_REG = 0x3,
MCU_CMD_NIC_POWER_CTRL = MCU_FW_PREFIX | 0x4,
MCU_CMD_PATCH_START_REQ = MCU_FW_PREFIX | 0x05,
MCU_CMD_PATCH_FINISH_REQ = MCU_FW_PREFIX | 0x07,
MCU_CMD_PATCH_SEM_CONTROL = MCU_FW_PREFIX | 0x10,
MCU_CMD_NIC_POWER_CTRL = 0x4,
MCU_CMD_PATCH_START_REQ = 0x05,
MCU_CMD_PATCH_FINISH_REQ = 0x07,
MCU_CMD_PATCH_SEM_CONTROL = 0x10,
MCU_CMD_WA_PARAM = 0xc4,
MCU_CMD_EXT_CID = 0xed,
MCU_CMD_FW_SCATTER = MCU_FW_PREFIX | 0xee,
MCU_CMD_RESTART_DL_REQ = MCU_FW_PREFIX | 0xef,
MCU_CMD_FW_SCATTER = 0xee,
MCU_CMD_RESTART_DL_REQ = 0xef,
};
/* offload mcu commands */
enum {
MCU_CMD_TEST_CTRL = MCU_CE_PREFIX | 0x01,
MCU_CMD_START_HW_SCAN = MCU_CE_PREFIX | 0x03,
MCU_CMD_SET_PS_PROFILE = MCU_CE_PREFIX | 0x05,
MCU_CMD_SET_CHAN_DOMAIN = MCU_CE_PREFIX | 0x0f,
MCU_CMD_SET_BSS_CONNECTED = MCU_CE_PREFIX | 0x16,
MCU_CMD_SET_BSS_ABORT = MCU_CE_PREFIX | 0x17,
MCU_CMD_CANCEL_HW_SCAN = MCU_CE_PREFIX | 0x1b,
MCU_CMD_SET_ROC = MCU_CE_PREFIX | 0x1d,
MCU_CMD_SET_P2P_OPPPS = MCU_CE_PREFIX | 0x33,
MCU_CMD_SET_RATE_TX_POWER = MCU_CE_PREFIX | 0x5d,
MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62,
MCU_CMD_GET_NIC_CAPAB = MCU_CE_PREFIX | 0x8a,
MCU_CMD_SET_MU_EDCA_PARMS = MCU_CE_PREFIX | 0xb0,
MCU_CMD_REG_WRITE = MCU_CE_PREFIX | 0xc0,
MCU_CMD_REG_READ = MCU_CE_PREFIX | MCU_QUERY_MASK | 0xc0,
MCU_CMD_CHIP_CONFIG = MCU_CE_PREFIX | 0xca,
MCU_CMD_FWLOG_2_HOST = MCU_CE_PREFIX | 0xc5,
MCU_CMD_GET_WTBL = MCU_CE_PREFIX | 0xcd,
MCU_CMD_GET_TXPWR = MCU_CE_PREFIX | 0xd0,
MCU_CE_CMD_TEST_CTRL = 0x01,
MCU_CE_CMD_START_HW_SCAN = 0x03,
MCU_CE_CMD_SET_PS_PROFILE = 0x05,
MCU_CE_CMD_SET_CHAN_DOMAIN = 0x0f,
MCU_CE_CMD_SET_BSS_CONNECTED = 0x16,
MCU_CE_CMD_SET_BSS_ABORT = 0x17,
MCU_CE_CMD_CANCEL_HW_SCAN = 0x1b,
MCU_CE_CMD_SET_ROC = 0x1d,
MCU_CE_CMD_SET_P2P_OPPPS = 0x33,
MCU_CE_CMD_SET_RATE_TX_POWER = 0x5d,
MCU_CE_CMD_SCHED_SCAN_ENABLE = 0x61,
MCU_CE_CMD_SCHED_SCAN_REQ = 0x62,
MCU_CE_CMD_GET_NIC_CAPAB = 0x8a,
MCU_CE_CMD_SET_MU_EDCA_PARMS = 0xb0,
MCU_CE_CMD_REG_WRITE = 0xc0,
MCU_CE_CMD_REG_READ = 0xc0,
MCU_CE_CMD_CHIP_CONFIG = 0xca,
MCU_CE_CMD_FWLOG_2_HOST = 0xc5,
MCU_CE_CMD_GET_WTBL = 0xcd,
MCU_CE_CMD_GET_TXPWR = 0xd0,
};
enum {

View file

@ -237,7 +237,10 @@ int mt76x0_register_device(struct mt76x02_dev *dev)
{
int ret;
mt76x02_init_device(dev);
ret = mt76x02_init_device(dev);
if (ret)
return ret;
mt76x02_config_mac_addr_list(dev);
ret = mt76_register_device(&dev->mt76, true, mt76x02_rates,

View file

@ -31,6 +31,32 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
mt76_txq_schedule_all(&dev->mphy);
}
int mt76x0_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
int err = -EINVAL, power = hw->conf.power_level * 2;
struct mt76x02_dev *dev = hw->priv;
struct mt76_phy *mphy = &dev->mphy;
mutex_lock(&dev->mt76.mutex);
if (!cfg80211_chandef_valid(&mphy->chandef))
goto out;
err = mt76_init_sar_power(hw, sar);
if (err)
goto out;
dev->txpower_conf = mt76_get_sar_power(mphy, mphy->chandef.chan,
power);
if (test_bit(MT76_STATE_RUNNING, &mphy->state))
mt76x0_phy_set_txpower(dev);
out:
mutex_unlock(&dev->mt76.mutex);
return err;
}
EXPORT_SYMBOL_GPL(mt76x0_set_sar_specs);
int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
{
struct mt76x02_dev *dev = hw->priv;
@ -44,9 +70,13 @@ int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {
dev->txpower_conf = hw->conf.power_level * 2;
struct mt76_phy *mphy = &dev->mphy;
if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
dev->txpower_conf = hw->conf.power_level * 2;
dev->txpower_conf = mt76_get_sar_power(mphy,
mphy->chandef.chan,
dev->txpower_conf);
if (test_bit(MT76_STATE_RUNNING, &mphy->state))
mt76x0_phy_set_txpower(dev);
}

View file

@ -49,6 +49,8 @@ void mt76x0_chip_onoff(struct mt76x02_dev *dev, bool enable, bool reset);
void mt76x0_mac_stop(struct mt76x02_dev *dev);
int mt76x0_config(struct ieee80211_hw *hw, u32 changed);
int mt76x0_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
/* PHY */
void mt76x0_phy_init(struct mt76x02_dev *dev);

View file

@ -85,6 +85,7 @@ static const struct ieee80211_ops mt76x0e_ops = {
.set_rts_threshold = mt76x02_set_rts_threshold,
.get_antenna = mt76_get_antenna,
.reconfig_complete = mt76x02_reconfig_complete,
.set_sar_specs = mt76x0_set_sar_specs,
};
static int mt76x0e_init_hardware(struct mt76x02_dev *dev, bool resume)

View file

@ -141,6 +141,7 @@ static const struct ieee80211_ops mt76x0u_ops = {
.set_tim = mt76_set_tim,
.release_buffered_frames = mt76_release_buffered_frames,
.get_antenna = mt76_get_antenna,
.set_sar_specs = mt76x0_set_sar_specs,
};
static int mt76x0u_init_hardware(struct mt76x02_dev *dev, bool reset)

View file

@ -133,7 +133,7 @@ struct mt76x02_dev {
extern struct ieee80211_rate mt76x02_rates[12];
void mt76x02_init_device(struct mt76x02_dev *dev);
int mt76x02_init_device(struct mt76x02_dev *dev);
void mt76x02_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags, u64 multicast);

View file

@ -138,7 +138,7 @@ mt76x02_led_set_brightness(struct led_classdev *led_cdev,
mt76x02_led_set_config(mdev, 0xff, 0);
}
void mt76x02_init_device(struct mt76x02_dev *dev)
int mt76x02_init_device(struct mt76x02_dev *dev)
{
struct ieee80211_hw *hw = mt76_hw(dev);
struct wiphy *wiphy = hw->wiphy;
@ -197,6 +197,8 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
dev->mphy.chainmask = 0x101;
dev->mphy.antenna_mask = 1;
}
return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_init_device);

View file

@ -8,6 +8,35 @@
#include "eeprom.h"
#include "../mt76x02_phy.h"
int mt76x2_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
int err = -EINVAL, power = hw->conf.power_level * 2;
struct mt76x02_dev *dev = hw->priv;
struct mt76_phy *mphy = &dev->mphy;
mutex_lock(&dev->mt76.mutex);
if (!cfg80211_chandef_valid(&mphy->chandef))
goto out;
err = mt76_init_sar_power(hw, sar);
if (err)
goto out;
dev->txpower_conf = mt76_get_sar_power(mphy, mphy->chandef.chan,
power);
/* convert to per-chain power for 2x2 devices */
dev->txpower_conf -= 6;
if (test_bit(MT76_STATE_RUNNING, &mphy->state))
mt76x2_phy_set_txpower(dev);
out:
mutex_unlock(&dev->mt76.mutex);
return err;
}
EXPORT_SYMBOL_GPL(mt76x2_set_sar_specs);
static void
mt76x2_set_wlan_state(struct mt76x02_dev *dev, bool enable)
{

View file

@ -41,6 +41,8 @@ extern const struct ieee80211_ops mt76x2_ops;
int mt76x2_register_device(struct mt76x02_dev *dev);
int mt76x2_resume_device(struct mt76x02_dev *dev);
int mt76x2_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar);
void mt76x2_phy_power_on(struct mt76x02_dev *dev);
void mt76x2_stop_hardware(struct mt76x02_dev *dev);
int mt76x2_eeprom_init(struct mt76x02_dev *dev);

View file

@ -292,8 +292,9 @@ int mt76x2_register_device(struct mt76x02_dev *dev)
int ret;
INIT_DELAYED_WORK(&dev->cal_work, mt76x2_phy_calibrate);
mt76x02_init_device(dev);
ret = mt76x02_init_device(dev);
if (ret)
return ret;
ret = mt76x2_init_hardware(dev);
if (ret)

View file

@ -78,8 +78,12 @@ mt76x2_config(struct ieee80211_hw *hw, u32 changed)
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {
dev->txpower_conf = hw->conf.power_level * 2;
struct mt76_phy *mphy = &dev->mphy;
dev->txpower_conf = hw->conf.power_level * 2;
dev->txpower_conf = mt76_get_sar_power(mphy,
mphy->chandef.chan,
dev->txpower_conf);
/* convert to per-chain power for 2x2 devices */
dev->txpower_conf -= 6;
@ -155,5 +159,6 @@ const struct ieee80211_ops mt76x2_ops = {
.get_antenna = mt76_get_antenna,
.set_rts_threshold = mt76x02_set_rts_threshold,
.reconfig_complete = mt76x02_reconfig_complete,
.set_sar_specs = mt76x2_set_sar_specs,
};

View file

@ -194,7 +194,9 @@ int mt76x2u_register_device(struct mt76x02_dev *dev)
int err;
INIT_DELAYED_WORK(&dev->cal_work, mt76x2u_phy_calibrate);
mt76x02_init_device(dev);
err = mt76x02_init_device(dev);
if (err)
return err;
err = mt76x2u_init_eeprom(dev);
if (err < 0)

View file

@ -78,12 +78,16 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
}
if (changed & IEEE80211_CONF_CHANGE_POWER) {
dev->txpower_conf = hw->conf.power_level * 2;
struct mt76_phy *mphy = &dev->mphy;
dev->txpower_conf = hw->conf.power_level * 2;
dev->txpower_conf = mt76_get_sar_power(mphy,
mphy->chandef.chan,
dev->txpower_conf);
/* convert to per-chain power for 2x2 devices */
dev->txpower_conf -= 6;
if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
if (test_bit(MT76_STATE_RUNNING, &mphy->state))
mt76x2_phy_set_txpower(dev);
}
@ -121,4 +125,5 @@ const struct ieee80211_ops mt76x2u_ops = {
.set_tim = mt76_set_tim,
.release_buffered_frames = mt76_release_buffered_frames,
.get_antenna = mt76_get_antenna,
.set_sar_specs = mt76x2_set_sar_specs,
};

View file

@ -81,6 +81,225 @@ mt7915_radar_trigger(void *data, u64 val)
DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL,
mt7915_radar_trigger, "%lld\n");
static int
mt7915_muru_debug_set(void *data, u64 val)
{
struct mt7915_dev *dev = data;
dev->muru_debug = val;
mt7915_mcu_muru_debug_set(dev, data);
return 0;
}
static int
mt7915_muru_debug_get(void *data, u64 *val)
{
struct mt7915_dev *dev = data;
*val = dev->muru_debug;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_muru_debug, mt7915_muru_debug_get,
mt7915_muru_debug_set, "%lld\n");
static int mt7915_muru_stats_show(struct seq_file *file, void *data)
{
struct mt7915_phy *phy = file->private;
struct mt7915_dev *dev = phy->dev;
struct mt7915_mcu_muru_stats mu_stats = {};
static const char * const dl_non_he_type[] = {
"CCK", "OFDM", "HT MIX", "HT GF",
"VHT SU", "VHT 2MU", "VHT 3MU", "VHT 4MU"
};
static const char * const dl_he_type[] = {
"HE SU", "HE EXT", "HE 2MU", "HE 3MU", "HE 4MU",
"HE 2RU", "HE 3RU", "HE 4RU", "HE 5-8RU", "HE 9-16RU",
"HE >16RU"
};
static const char * const ul_he_type[] = {
"HE 2MU", "HE 3MU", "HE 4MU", "HE SU", "HE 2RU",
"HE 3RU", "HE 4RU", "HE 5-8RU", "HE 9-16RU", "HE >16RU"
};
int ret, i;
u64 total_ppdu_cnt, sub_total_cnt;
if (!dev->muru_debug) {
seq_puts(file, "Please enable muru_debug first.\n");
return 0;
}
mutex_lock(&dev->mt76.mutex);
ret = mt7915_mcu_muru_debug_get(phy, &mu_stats);
if (ret)
goto exit;
/* Non-HE Downlink*/
seq_puts(file, "[Non-HE]\nDownlink\nData Type: ");
for (i = 0; i < 5; i++)
seq_printf(file, "%8s | ", dl_non_he_type[i]);
#define __dl_u32(s) le32_to_cpu(mu_stats.dl.s)
seq_puts(file, "\nTotal Count:");
seq_printf(file, "%8u | %8u | %8u | %8u | %8u | ",
__dl_u32(cck_cnt),
__dl_u32(ofdm_cnt),
__dl_u32(htmix_cnt),
__dl_u32(htgf_cnt),
__dl_u32(vht_su_cnt));
seq_puts(file, "\nDownlink MU-MIMO\nData Type: ");
for (i = 5; i < 8; i++)
seq_printf(file, "%8s | ", dl_non_he_type[i]);
seq_puts(file, "\nTotal Count:");
seq_printf(file, "%8u | %8u | %8u | ",
__dl_u32(vht_2mu_cnt),
__dl_u32(vht_3mu_cnt),
__dl_u32(vht_4mu_cnt));
sub_total_cnt = __dl_u32(vht_2mu_cnt) +
__dl_u32(vht_3mu_cnt) +
__dl_u32(vht_4mu_cnt);
seq_printf(file, "\nTotal non-HE MU-MIMO DL PPDU count: %lld",
sub_total_cnt);
total_ppdu_cnt = sub_total_cnt +
__dl_u32(cck_cnt) +
__dl_u32(ofdm_cnt) +
__dl_u32(htmix_cnt) +
__dl_u32(htgf_cnt) +
__dl_u32(vht_su_cnt);
seq_printf(file, "\nAll non-HE DL PPDU count: %lld", total_ppdu_cnt);
/* HE Downlink */
seq_puts(file, "\n\n[HE]\nDownlink\nData Type: ");
for (i = 0; i < 2; i++)
seq_printf(file, "%8s | ", dl_he_type[i]);
seq_puts(file, "\nTotal Count:");
seq_printf(file, "%8u | %8u | ",
__dl_u32(he_su_cnt),
__dl_u32(he_ext_su_cnt));
seq_puts(file, "\nDownlink MU-MIMO\nData Type: ");
for (i = 2; i < 5; i++)
seq_printf(file, "%8s | ", dl_he_type[i]);
seq_puts(file, "\nTotal Count:");
seq_printf(file, "%8u | %8u | %8u | ",
__dl_u32(he_2mu_cnt),
__dl_u32(he_3mu_cnt),
__dl_u32(he_4mu_cnt));
seq_puts(file, "\nDownlink OFDMA\nData Type: ");
for (i = 5; i < 11; i++)
seq_printf(file, "%8s | ", dl_he_type[i]);
seq_puts(file, "\nTotal Count:");
seq_printf(file, "%8u | %8u | %8u | %8u | %9u | %8u | ",
__dl_u32(he_2ru_cnt),
__dl_u32(he_3ru_cnt),
__dl_u32(he_4ru_cnt),
__dl_u32(he_5to8ru_cnt),
__dl_u32(he_9to16ru_cnt),
__dl_u32(he_gtr16ru_cnt));
sub_total_cnt = __dl_u32(he_2mu_cnt) +
__dl_u32(he_3mu_cnt) +
__dl_u32(he_4mu_cnt);
total_ppdu_cnt = sub_total_cnt;
seq_printf(file, "\nTotal HE MU-MIMO DL PPDU count: %lld",
sub_total_cnt);
sub_total_cnt = __dl_u32(he_2ru_cnt) +
__dl_u32(he_3ru_cnt) +
__dl_u32(he_4ru_cnt) +
__dl_u32(he_5to8ru_cnt) +
__dl_u32(he_9to16ru_cnt) +
__dl_u32(he_gtr16ru_cnt);
total_ppdu_cnt += sub_total_cnt;
seq_printf(file, "\nTotal HE OFDMA DL PPDU count: %lld",
sub_total_cnt);
total_ppdu_cnt += __dl_u32(he_su_cnt) +
__dl_u32(he_ext_su_cnt);
seq_printf(file, "\nAll HE DL PPDU count: %lld", total_ppdu_cnt);
#undef __dl_u32
/* HE Uplink */
seq_puts(file, "\n\nUplink");
seq_puts(file, "\nTrigger-based Uplink MU-MIMO\nData Type: ");
for (i = 0; i < 3; i++)
seq_printf(file, "%8s | ", ul_he_type[i]);
#define __ul_u32(s) le32_to_cpu(mu_stats.ul.s)
seq_puts(file, "\nTotal Count:");
seq_printf(file, "%8u | %8u | %8u | ",
__ul_u32(hetrig_2mu_cnt),
__ul_u32(hetrig_3mu_cnt),
__ul_u32(hetrig_4mu_cnt));
seq_puts(file, "\nTrigger-based Uplink OFDMA\nData Type: ");
for (i = 3; i < 10; i++)
seq_printf(file, "%8s | ", ul_he_type[i]);
seq_puts(file, "\nTotal Count:");
seq_printf(file, "%8u | %8u | %8u | %8u | %8u | %9u | %7u | ",
__ul_u32(hetrig_su_cnt),
__ul_u32(hetrig_2ru_cnt),
__ul_u32(hetrig_3ru_cnt),
__ul_u32(hetrig_4ru_cnt),
__ul_u32(hetrig_5to8ru_cnt),
__ul_u32(hetrig_9to16ru_cnt),
__ul_u32(hetrig_gtr16ru_cnt));
sub_total_cnt = __ul_u32(hetrig_2mu_cnt) +
__ul_u32(hetrig_3mu_cnt) +
__ul_u32(hetrig_4mu_cnt);
total_ppdu_cnt = sub_total_cnt;
seq_printf(file, "\nTotal HE MU-MIMO UL TB PPDU count: %lld",
sub_total_cnt);
sub_total_cnt = __ul_u32(hetrig_2ru_cnt) +
__ul_u32(hetrig_3ru_cnt) +
__ul_u32(hetrig_4ru_cnt) +
__ul_u32(hetrig_5to8ru_cnt) +
__ul_u32(hetrig_9to16ru_cnt) +
__ul_u32(hetrig_gtr16ru_cnt);
total_ppdu_cnt += sub_total_cnt;
seq_printf(file, "\nTotal HE OFDMA UL TB PPDU count: %lld",
sub_total_cnt);
total_ppdu_cnt += __ul_u32(hetrig_su_cnt);
seq_printf(file, "\nAll HE UL TB PPDU count: %lld\n", total_ppdu_cnt);
#undef __ul_u32
exit:
mutex_unlock(&dev->mt76.mutex);
return ret;
}
DEFINE_SHOW_ATTRIBUTE(mt7915_muru_stats);
static int
mt7915_fw_debug_wm_set(void *data, u64 val)
{
@ -355,8 +574,8 @@ mt7915_sta_hw_queue_read(void *data, struct ieee80211_sta *sta)
qlen = mt76_get_field(dev, MT_PLE_BASE + MT_FL_Q3_CTRL,
GENMASK(11, 0));
seq_printf(s, "\tSTA %pM wcid %d: AC%d%d queued:%d\n",
sta->addr, msta->wcid.idx, msta->vif->wmm_idx,
ac, qlen);
sta->addr, msta->wcid.idx,
msta->vif->mt76.wmm_idx, ac, qlen);
}
}
@ -528,7 +747,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
dir = mt76_register_debugfs_fops(phy->mt76, NULL);
if (!dir)
return -ENOMEM;
debugfs_create_file("muru_debug", 0600, dir, dev, &fops_muru_debug);
debugfs_create_file("muru_stats", 0400, dir, phy,
&mt7915_muru_stats_fops);
debugfs_create_file("hw-queues", 0400, dir, phy,
&mt7915_hw_queues_fops);
debugfs_create_file("xmit-queues", 0400, dir, phy,

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: ISC
/* Copyright (C) 2020 MediaTek Inc. */
#include <linux/firmware.h>
#include "mt7915.h"
#include "eeprom.h"
@ -10,6 +11,9 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
u8 *eeprom = mdev->eeprom.data;
u32 val = eeprom[MT_EE_DO_PRE_CAL];
if (!dev->flash_mode)
return 0;
if (val != (MT_EE_WIFI_CAL_DPD | MT_EE_WIFI_CAL_GROUP))
return 0;
@ -21,30 +25,6 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev)
return mt76_get_of_eeprom(mdev, dev->cal, MT_EE_PRECAL, val);
}
static int mt7915_eeprom_load(struct mt7915_dev *dev)
{
int ret;
ret = mt76_eeprom_init(&dev->mt76, MT7915_EEPROM_SIZE);
if (ret < 0)
return ret;
if (ret) {
dev->flash_mode = true;
ret = mt7915_eeprom_load_precal(dev);
} else {
u32 block_num, i;
block_num = DIV_ROUND_UP(MT7915_EEPROM_SIZE,
MT7915_EEPROM_BLOCK_SIZE);
for (i = 0; i < block_num; i++)
mt7915_mcu_get_eeprom(dev,
i * MT7915_EEPROM_BLOCK_SIZE);
}
return ret;
}
static int mt7915_check_eeprom(struct mt7915_dev *dev)
{
u8 *eeprom = dev->mt76.eeprom.data;
@ -58,6 +38,66 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev)
}
}
static int
mt7915_eeprom_load_default(struct mt7915_dev *dev)
{
char *default_bin = MT7915_EEPROM_DEFAULT;
u8 *eeprom = dev->mt76.eeprom.data;
const struct firmware *fw = NULL;
int ret;
if (dev->dbdc_support)
default_bin = MT7915_EEPROM_DEFAULT_DBDC;
ret = request_firmware(&fw, default_bin, dev->mt76.dev);
if (ret)
return ret;
if (!fw || !fw->data) {
dev_err(dev->mt76.dev, "Invalid default bin\n");
ret = -EINVAL;
goto out;
}
memcpy(eeprom, fw->data, MT7915_EEPROM_SIZE);
dev->flash_mode = true;
out:
release_firmware(fw);
return ret;
}
static int mt7915_eeprom_load(struct mt7915_dev *dev)
{
int ret;
ret = mt76_eeprom_init(&dev->mt76, MT7915_EEPROM_SIZE);
if (ret < 0)
return ret;
if (ret) {
dev->flash_mode = true;
} else {
u8 free_block_num;
u32 block_num, i;
mt7915_mcu_get_eeprom_free_block(dev, &free_block_num);
/* efuse info not enough */
if (free_block_num >= 29)
return -EINVAL;
/* read eeprom data from efuse */
block_num = DIV_ROUND_UP(MT7915_EEPROM_SIZE,
MT7915_EEPROM_BLOCK_SIZE);
for (i = 0; i < block_num; i++)
mt7915_mcu_get_eeprom(dev,
i * MT7915_EEPROM_BLOCK_SIZE);
}
return mt7915_check_eeprom(dev);
}
void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
@ -117,10 +157,17 @@ int mt7915_eeprom_init(struct mt7915_dev *dev)
int ret;
ret = mt7915_eeprom_load(dev);
if (ret < 0)
return ret;
if (ret < 0) {
if (ret != -EINVAL)
return ret;
ret = mt7915_check_eeprom(dev);
dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
ret = mt7915_eeprom_load_default(dev);
if (ret)
return ret;
}
ret = mt7915_eeprom_load_precal(dev);
if (ret)
return ret;

View file

@ -268,10 +268,9 @@ mt7915_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
}
static void
mt7915_mac_decode_he_mu_radiotap(struct sk_buff *skb,
struct mt76_rx_status *status,
__le32 *rxv)
mt7915_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
static const struct ieee80211_radiotap_he_mu mu_known = {
.flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
@ -281,6 +280,8 @@ mt7915_mac_decode_he_mu_radiotap(struct sk_buff *skb,
};
struct ieee80211_radiotap_he_mu *he_mu = NULL;
status->flag |= RX_FLAG_RADIOTAP_HE_MU;
he_mu = skb_push(skb, sizeof(mu_known));
memcpy(he_mu, &mu_known, sizeof(mu_known));
@ -308,10 +309,9 @@ mt7915_mac_decode_he_mu_radiotap(struct sk_buff *skb,
}
static void
mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
struct mt76_rx_status *status,
__le32 *rxv, u32 phy)
mt7915_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u32 mode)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
static const struct ieee80211_radiotap_he known = {
.data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
HE_BITS(DATA1_DATA_DCM_KNOWN) |
@ -329,6 +329,8 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
struct ieee80211_radiotap_he *he = NULL;
u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1;
status->flag |= RX_FLAG_RADIOTAP_HE;
he = skb_push(skb, sizeof(known));
memcpy(he, &known, sizeof(known));
@ -343,7 +345,7 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) |
HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]);
switch (phy) {
switch (mode) {
case MT_PHY_TYPE_HE_SU:
he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
HE_BITS(DATA1_UL_DL_KNOWN) |
@ -366,6 +368,7 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]);
mt7915_mac_decode_he_radiotap_ru(status, he, rxv);
mt7915_mac_decode_he_mu_radiotap(skb, rxv);
break;
case MT_PHY_TYPE_HE_TB:
he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
@ -384,6 +387,81 @@ mt7915_mac_decode_he_radiotap(struct sk_buff *skb,
}
}
/* The HW does not translate the mac header to 802.3 for mesh point */
static int mt7915_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
struct mt7915_sta *msta = (struct mt7915_sta *)status->wcid;
struct ieee80211_sta *sta;
struct ieee80211_vif *vif;
struct ieee80211_hdr hdr;
struct ethhdr eth_hdr;
__le32 *rxd = (__le32 *)skb->data;
__le32 qos_ctrl, ht_ctrl;
if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) !=
MT_RXD3_NORMAL_U2M)
return -EINVAL;
if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4))
return -EINVAL;
if (!msta || !msta->vif)
return -EINVAL;
sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
/* store the info from RXD and ethhdr to avoid being overridden */
memcpy(&eth_hdr, skb->data + hdr_gap, sizeof(eth_hdr));
hdr.frame_control = FIELD_GET(MT_RXD6_FRAME_CONTROL, rxd[6]);
hdr.seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, rxd[8]);
qos_ctrl = FIELD_GET(MT_RXD8_QOS_CTL, rxd[8]);
ht_ctrl = FIELD_GET(MT_RXD9_HT_CONTROL, rxd[9]);
hdr.duration_id = 0;
ether_addr_copy(hdr.addr1, vif->addr);
ether_addr_copy(hdr.addr2, sta->addr);
switch (le16_to_cpu(hdr.frame_control) &
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case 0:
ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
break;
case IEEE80211_FCTL_FROMDS:
ether_addr_copy(hdr.addr3, eth_hdr.h_source);
break;
case IEEE80211_FCTL_TODS:
ether_addr_copy(hdr.addr3, eth_hdr.h_dest);
break;
case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS:
ether_addr_copy(hdr.addr3, eth_hdr.h_dest);
ether_addr_copy(hdr.addr4, eth_hdr.h_source);
break;
default:
break;
}
skb_pull(skb, hdr_gap + sizeof(struct ethhdr) - 2);
if (eth_hdr.h_proto == htons(ETH_P_AARP) ||
eth_hdr.h_proto == htons(ETH_P_IPX))
ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
else if (eth_hdr.h_proto >= htons(ETH_P_802_3_MIN))
ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
else
skb_pull(skb, 2);
if (ieee80211_has_order(hdr.frame_control))
memcpy(skb_push(skb, 2), &ht_ctrl, 2);
if (ieee80211_is_data_qos(hdr.frame_control))
memcpy(skb_push(skb, 2), &qos_ctrl, 2);
if (ieee80211_has_a4(hdr.frame_control))
memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
else
memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6);
return 0;
}
static int
mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
{
@ -391,7 +469,6 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
struct mt76_phy *mphy = &dev->mt76.phy;
struct mt7915_phy *phy = &dev->phy;
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
__le32 *rxd = (__le32 *)skb->data;
__le32 *rxv = NULL;
u32 mode = 0;
@ -404,6 +481,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
bool unicast, insert_ccmp_hdr = false;
u8 remove_pad, amsdu_info;
bool hdr_trans;
u16 hdr_gap;
u16 seq_ctrl = 0;
u8 qos_ctl = 0;
__le16 fc = 0;
@ -426,9 +504,16 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
return -EINVAL;
hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
return -EINVAL;
/* ICV error or CCMP/BIP/WPI MIC error */
if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
status->flag |= RX_FLAG_ONLY_MONITOR;
unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
status->wcid = mt7915_rx_get_wcid(dev, idx, unicast);
if (status->wcid) {
@ -604,15 +689,12 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
return -EINVAL;
break;
case MT_PHY_TYPE_HE_MU:
status->flag |= RX_FLAG_RADIOTAP_HE_MU;
fallthrough;
case MT_PHY_TYPE_HE_SU:
case MT_PHY_TYPE_HE_EXT_SU:
case MT_PHY_TYPE_HE_TB:
status->nss =
FIELD_GET(MT_PRXV_NSTS, v0) + 1;
status->encoding = RX_ENC_HE;
status->flag |= RX_FLAG_RADIOTAP_HE;
i &= GENMASK(3, 0);
if (gi <= NL80211_RATE_INFO_HE_GI_3_2)
@ -654,27 +736,55 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
}
}
skb_pull(skb, (u8 *)rxd - skb->data + 2 * remove_pad);
amsdu_info = FIELD_GET(MT_RXD4_NORMAL_PAYLOAD_FORMAT, rxd4);
status->amsdu = !!amsdu_info;
if (status->amsdu) {
status->first_amsdu = amsdu_info == MT_RXD4_FIRST_AMSDU_FRAME;
status->last_amsdu = amsdu_info == MT_RXD4_LAST_AMSDU_FRAME;
if (!hdr_trans) {
memmove(skb->data + 2, skb->data,
ieee80211_get_hdrlen_from_skb(skb));
}
hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad;
if (hdr_trans && ieee80211_has_morefrags(fc)) {
if (mt7915_reverse_frag0_hdr_trans(skb, hdr_gap))
return -EINVAL;
hdr_trans = false;
} else {
int pad_start = 0;
skb_pull(skb, hdr_gap);
if (!hdr_trans && status->amsdu) {
pad_start = ieee80211_get_hdrlen_from_skb(skb);
} else if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_HDR_TRANS_ERROR)) {
/*
* When header translation failure is indicated,
* the hardware will insert an extra 2-byte field
* containing the data length after the protocol
* type field.
*/
pad_start = 12;
if (get_unaligned_be16(skb->data + pad_start) == ETH_P_8021Q)
pad_start += 4;
if (get_unaligned_be16(skb->data + pad_start) !=
skb->len - pad_start - 2)
pad_start = 0;
}
if (pad_start) {
memmove(skb->data + 2, skb->data, pad_start);
skb_pull(skb, 2);
}
}
if (insert_ccmp_hdr && !hdr_trans) {
u8 key_id = FIELD_GET(MT_RXD1_NORMAL_KEY_ID, rxd1);
mt76_insert_ccmp_hdr(skb, key_id);
}
if (!hdr_trans) {
struct ieee80211_hdr *hdr;
if (insert_ccmp_hdr) {
u8 key_id = FIELD_GET(MT_RXD1_NORMAL_KEY_ID, rxd1);
mt76_insert_ccmp_hdr(skb, key_id);
}
hdr = mt76_skb_get_hdr(skb);
fc = hdr->frame_control;
if (ieee80211_is_data_qos(fc)) {
@ -682,16 +792,11 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
qos_ctl = *ieee80211_get_qos_ctl(hdr);
}
} else {
status->flag &= ~(RX_FLAG_RADIOTAP_HE |
RX_FLAG_RADIOTAP_HE_MU);
status->flag |= RX_FLAG_8023;
}
if (rxv && status->flag & RX_FLAG_RADIOTAP_HE) {
mt7915_mac_decode_he_radiotap(skb, status, rxv, mode);
if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
mt7915_mac_decode_he_mu_radiotap(skb, status, rxv);
}
if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
mt7915_mac_decode_he_radiotap(skb, rxv, mode);
if (!status->wcid || !ieee80211_is_data_qos(fc))
return 0;
@ -1044,8 +1149,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
if (vif) {
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
omac_idx = mvif->omac_idx;
wmm_idx = mvif->wmm_idx;
omac_idx = mvif->mt76.omac_idx;
wmm_idx = mvif->mt76.wmm_idx;
}
if (ext_phy && dev->mt76.phy2)
@ -1181,7 +1286,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
if (vif) {
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
txp->bss_idx = mvif->idx;
txp->bss_idx = mvif->mt76.idx;
}
txp->token = cpu_to_le16(id);
@ -1268,15 +1373,16 @@ mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t,
}
static void
mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len)
{
struct mt7915_tx_free *free = (struct mt7915_tx_free *)skb->data;
struct mt7915_tx_free *free = (struct mt7915_tx_free *)data;
struct mt76_dev *mdev = &dev->mt76;
struct mt76_phy *mphy_ext = mdev->phy2;
struct mt76_txwi_cache *txwi;
struct ieee80211_sta *sta = NULL;
LIST_HEAD(free_list);
struct sk_buff *tmp;
struct sk_buff *skb, *tmp;
void *end = data + len;
u8 i, count;
bool wake = false;
@ -1294,6 +1400,9 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
* Should avoid accessing WTBL to get Tx airtime, and use it instead.
*/
count = FIELD_GET(MT_TX_FREE_MSDU_CNT, le16_to_cpu(free->ctrl));
if (WARN_ON_ONCE((void *)&free->info[count] > end))
return;
for (i = 0; i < count; i++) {
u32 msdu, info = le32_to_cpu(free->info[i]);
@ -1336,8 +1445,6 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, struct sk_buff *skb)
mt76_worker_schedule(&dev->mt76.tx_worker);
napi_consume_skb(skb, 1);
list_for_each_entry_safe(skb, tmp, &free_list, list) {
skb_list_del_init(skb);
napi_consume_skb(skb, 1);
@ -1512,6 +1619,27 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data)
rcu_read_unlock();
}
bool mt7915_rx_check(struct mt76_dev *mdev, void *data, int len)
{
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
__le32 *rxd = (__le32 *)data;
__le32 *end = (__le32 *)&rxd[len / 4];
enum rx_pkt_type type;
type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
mt7915_mac_tx_free(dev, data, len);
return false;
case PKT_TYPE_TXS:
for (rxd += 2; rxd + 8 <= end; rxd += 8)
mt7915_mac_add_txs(dev, rxd);
return false;
default:
return true;
}
}
void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb)
{
@ -1524,7 +1652,8 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
switch (type) {
case PKT_TYPE_TXRX_NOTIFY:
mt7915_mac_tx_free(dev, skb);
mt7915_mac_tx_free(dev, skb->data, skb->len);
napi_consume_skb(skb, 1);
break;
case PKT_TYPE_RX_EVENT:
mt7915_mcu_rx_event(dev, skb);

View file

@ -203,8 +203,8 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
is_zero_ether_addr(vif->addr))
phy->monitor_vif = vif;
mvif->idx = ffs(~dev->mt76.vif_mask) - 1;
if (mvif->idx >= MT7915_MAX_INTERFACES) {
mvif->mt76.idx = ffs(~dev->mt76.vif_mask) - 1;
if (mvif->mt76.idx >= MT7915_MAX_INTERFACES) {
ret = -ENOSPC;
goto out;
}
@ -214,29 +214,27 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
ret = -ENOSPC;
goto out;
}
mvif->omac_idx = idx;
mvif->mt76.omac_idx = idx;
mvif->phy = phy;
mvif->band_idx = ext_phy;
mvif->mt76.band_idx = ext_phy;
if (dev->mt76.phy2)
mvif->wmm_idx = ext_phy * (MT7915_MAX_WMM_SETS / 2) +
mvif->idx % (MT7915_MAX_WMM_SETS / 2);
else
mvif->wmm_idx = mvif->idx % MT7915_MAX_WMM_SETS;
mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
if (ext_phy)
mvif->mt76.wmm_idx += 2;
ret = mt7915_mcu_add_dev_info(phy, vif, true);
if (ret)
goto out;
dev->mt76.vif_mask |= BIT(mvif->idx);
phy->omac_mask |= BIT_ULL(mvif->omac_idx);
dev->mt76.vif_mask |= BIT(mvif->mt76.idx);
phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
idx = MT7915_WTBL_RESERVED - mvif->idx;
idx = MT7915_WTBL_RESERVED - mvif->mt76.idx;
INIT_LIST_HEAD(&mvif->sta.rc_list);
INIT_LIST_HEAD(&mvif->sta.poll_list);
mvif->sta.wcid.idx = idx;
mvif->sta.wcid.ext_phy = mvif->band_idx;
mvif->sta.wcid.ext_phy = mvif->mt76.band_idx;
mvif->sta.wcid.hw_key_idx = -1;
mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;
mt76_packet_id_init(&mvif->sta.wcid);
@ -251,7 +249,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
}
if (vif->type != NL80211_IFTYPE_AP &&
(!mvif->omac_idx || mvif->omac_idx > 3))
(!mvif->mt76.omac_idx || mvif->mt76.omac_idx > 3))
vif->offload_flags = 0;
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
@ -288,8 +286,8 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
mutex_lock(&dev->mt76.mutex);
dev->mt76.vif_mask &= ~BIT(mvif->idx);
phy->omac_mask &= ~BIT_ULL(mvif->omac_idx);
dev->mt76.vif_mask &= ~BIT(mvif->mt76.idx);
phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
mutex_unlock(&dev->mt76.mutex);
spin_lock_bh(&dev->sta_poll_lock);
@ -425,6 +423,28 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return err;
}
static int mt7915_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt7915_dev *dev = mt7915_hw_dev(hw);
int err = -EINVAL;
mutex_lock(&dev->mt76.mutex);
if (!cfg80211_chandef_valid(&phy->mt76->chandef))
goto out;
err = mt76_init_sar_power(hw, sar);
if (err)
goto out;
err = mt7915_mcu_set_txpower_sku(phy);
out:
mutex_unlock(&dev->mt76.mutex);
return err;
}
static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
{
struct mt7915_dev *dev = mt7915_hw_dev(hw);
@ -556,7 +576,7 @@ mt7915_update_bss_color(struct ieee80211_hw *hw,
case NL80211_IFTYPE_AP: {
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
if (mvif->omac_idx > HW_BSSID_MAX)
if (mvif->mt76.omac_idx > HW_BSSID_MAX)
return;
fallthrough;
}
@ -655,7 +675,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
msta->vif = mvif;
msta->wcid.sta = 1;
msta->wcid.idx = idx;
msta->wcid.ext_phy = mvif->band_idx;
msta->wcid.ext_phy = mvif->mt76.band_idx;
msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
msta->jiffies = jiffies;
@ -838,7 +858,8 @@ u64 __mt7915_get_tsf(struct ieee80211_hw *hw, struct mt7915_vif *mvif)
lockdep_assert_held(&dev->mt76.mutex);
n = mvif->omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : mvif->omac_idx;
n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0
: mvif->mt76.omac_idx;
/* TSF software read */
mt76_rmw(dev, MT_LPON_TCR(band, n), MT_LPON_TCR_SW_MODE,
MT_LPON_TCR_SW_READ);
@ -878,7 +899,8 @@ mt7915_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mt76.mutex);
n = mvif->omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : mvif->omac_idx;
n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0
: mvif->mt76.omac_idx;
mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);
mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);
/* TSF software overwrite */
@ -904,7 +926,8 @@ mt7915_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mt76.mutex);
n = mvif->omac_idx > HW_BSSID_MAX ? HW_BSSID_0 : mvif->omac_idx;
n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0
: mvif->mt76.omac_idx;
mt76_wr(dev, MT_LPON_UTTR0(band), tsf.t32[0]);
mt76_wr(dev, MT_LPON_UTTR1(band), tsf.t32[1]);
/* TSF software adjust*/
@ -1195,7 +1218,7 @@ static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta)
struct mt76_ethtool_worker_info *wi = wi_data;
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
if (msta->vif->idx != wi->idx)
if (msta->vif->mt76.idx != wi->idx)
return;
mt76_ethtool_worker(wi, &msta->stats);
@ -1211,7 +1234,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt76_ethtool_worker_info wi = {
.data = data,
.idx = mvif->idx,
.idx = mvif->mt76.idx,
};
struct mib_stats *mib = &phy->mib;
/* See mt7915_ampdu_stat_read_phy, etc */
@ -1331,6 +1354,7 @@ const struct ieee80211_ops mt7915_ops = {
.sw_scan_complete = mt76_sw_scan_complete,
.release_buffered_frames = mt76_release_buffered_frames,
.get_txpower = mt76_get_txpower,
.set_sar_specs = mt7915_set_sar_specs,
.channel_switch_beacon = mt7915_channel_switch_beacon,
.get_stats = mt7915_get_stats,
.get_et_sset_count = mt7915_get_et_sset_count,

View file

@ -582,10 +582,10 @@ mt7915_mcu_alloc_sta_req(struct mt7915_dev *dev, struct mt7915_vif *mvif,
struct mt7915_sta *msta, int len)
{
struct sta_req_hdr hdr = {
.bss_idx = mvif->idx,
.bss_idx = mvif->mt76.idx,
.wlan_idx_lo = msta ? to_wcid_lo(msta->wcid.idx) : 0,
.wlan_idx_hi = msta ? to_wcid_hi(msta->wcid.idx) : 0,
.muar_idx = msta && msta->wcid.sta ? mvif->omac_idx : 0xe,
.muar_idx = msta && msta->wcid.sta ? mvif->mt76.omac_idx : 0xe,
.is_tlv_append = 1,
};
struct sk_buff *skb;
@ -613,7 +613,7 @@ mt7915_mcu_alloc_wtbl_req(struct mt7915_dev *dev, struct mt7915_sta *msta,
if (!nskb) {
nskb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
MT7915_WTBL_UPDATE_MAX_SIZE);
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
if (!nskb)
return ERR_PTR(-ENOMEM);
@ -725,7 +725,7 @@ mt7915_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
bss->network_type = cpu_to_le32(type);
bss->bmc_wcid_lo = to_wcid_lo(wlan_idx);
bss->bmc_wcid_hi = to_wcid_hi(wlan_idx);
bss->wmm_idx = mvif->wmm_idx;
bss->wmm_idx = mvif->mt76.wmm_idx;
bss->active = enable;
if (vif->type != NL80211_IFTYPE_MONITOR) {
@ -769,10 +769,11 @@ mt7915_mcu_bss_omac_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
}
omac = (struct bss_info_omac *)tlv;
idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
idx = mvif->mt76.omac_idx > EXT_BSSID_START ? HW_BSSID_0
: mvif->mt76.omac_idx;
omac->conn_type = cpu_to_le32(type);
omac->omac_idx = mvif->omac_idx;
omac->band_idx = mvif->band_idx;
omac->omac_idx = mvif->mt76.omac_idx;
omac->band_idx = mvif->mt76.band_idx;
omac->hw_bss_idx = idx;
}
@ -937,7 +938,7 @@ mt7915_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt7915_vif *mvif)
int ext_bss_idx, tsf_offset;
struct tlv *tlv;
ext_bss_idx = mvif->omac_idx - EXT_BSSID_START;
ext_bss_idx = mvif->mt76.omac_idx - EXT_BSSID_START;
if (ext_bss_idx < 0)
return;
@ -973,7 +974,7 @@ mt7915_mcu_muar_config(struct mt7915_phy *phy, struct ieee80211_vif *vif,
{
struct mt7915_dev *dev = phy->dev;
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
u32 idx = mvif->omac_idx - REPEATER_BSSID_START;
u32 idx = mvif->mt76.omac_idx - REPEATER_BSSID_START;
u32 mask = phy->omac_mask >> 32 & ~BIT(idx);
const u8 *addr = vif->addr;
struct {
@ -1011,7 +1012,7 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct sk_buff *skb;
if (mvif->omac_idx >= REPEATER_BSSID_START) {
if (mvif->mt76.omac_idx >= REPEATER_BSSID_START) {
mt7915_mcu_muar_config(phy, vif, false, enable);
mt7915_mcu_muar_config(phy, vif, true, enable);
}
@ -1039,8 +1040,8 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
if (vif->bss_conf.he_support)
mt7915_mcu_bss_he_tlv(skb, vif, phy);
if (mvif->omac_idx >= EXT_BSSID_START &&
mvif->omac_idx < REPEATER_BSSID_START)
if (mvif->mt76.omac_idx >= EXT_BSSID_START &&
mvif->mt76.omac_idx < REPEATER_BSSID_START)
mt7915_mcu_bss_ext_tlv(skb, mvif);
}
out:
@ -1204,7 +1205,7 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev,
msta->wcid.amsdu = false;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT7915_STA_UPDATE_MAX_SIZE);
MT76_CONNAC_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
@ -1223,7 +1224,7 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev,
return ret;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT7915_STA_UPDATE_MAX_SIZE);
MT76_CONNAC_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
@ -1265,7 +1266,7 @@ mt7915_mcu_wtbl_generic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
if (sta) {
memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
generic->partial_aid = cpu_to_le16(sta->aid);
generic->muar_idx = mvif->omac_idx;
generic->muar_idx = mvif->mt76.omac_idx;
generic->qos = sta->wme;
} else {
/* use BSSID in station mode */
@ -1738,7 +1739,8 @@ int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
struct wtbl_req_hdr *wtbl_hdr;
struct sk_buff *skb;
skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, MT7915_WTBL_UPDATE_MAX_SIZE);
skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
if (!skb)
return -ENOMEM;
@ -1752,33 +1754,6 @@ int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
true);
}
int mt7915_mcu_add_smps(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 wtbl_req_hdr *wtbl_hdr;
struct tlv *sta_wtbl;
struct sk_buff *skb;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT7915_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
sta_wtbl = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl,
&skb);
if (IS_ERR(wtbl_hdr))
return PTR_ERR(wtbl_hdr);
mt7915_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_hdr);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
static inline bool
mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool bfee)
@ -1954,7 +1929,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_phy *phy =
mvif->band_idx ? mt7915_ext_phy(dev) : &dev->phy;
mvif->mt76.band_idx ? mt7915_ext_phy(dev) : &dev->phy;
int tx_ant = hweight8(phy->mt76->chainmask) - 1;
struct sta_rec_bf *bf;
struct tlv *tlv;
@ -2021,7 +1996,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct mt7915_phy *phy =
mvif->band_idx ? mt7915_ext_phy(dev) : &dev->phy;
mvif->mt76.band_idx ? mt7915_ext_phy(dev) : &dev->phy;
int tx_ant = hweight8(phy->mt76->chainmask) - 1;
struct sta_rec_bfee *bfee;
struct tlv *tlv;
@ -2049,6 +2024,21 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
}
static enum mcu_mmps_mode
mt7915_mcu_get_mmps_mode(enum ieee80211_smps_mode smps)
{
switch (smps) {
case IEEE80211_SMPS_OFF:
return MCU_MMPS_DISABLE;
case IEEE80211_SMPS_STATIC:
return MCU_MMPS_STATIC;
case IEEE80211_SMPS_DYNAMIC:
return MCU_MMPS_DYNAMIC;
default:
return MCU_MMPS_DISABLE;
}
}
int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@ -2076,7 +2066,11 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
case RATE_PARAM_FIXED_MCS:
case RATE_PARAM_FIXED_GI:
case RATE_PARAM_FIXED_HE_LTF:
ra->phy = *phy;
if (phy)
ra->phy = *phy;
break;
case RATE_PARAM_MMPS_UPDATE:
ra->mmps_mode = mt7915_mcu_get_mmps_mode(sta->smps_mode);
break;
default:
break;
@ -2087,6 +2081,39 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
int mt7915_mcu_add_smps(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 wtbl_req_hdr *wtbl_hdr;
struct tlv *sta_wtbl;
struct sk_buff *skb;
int ret;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT76_CONNAC_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
sta_wtbl = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl,
&skb);
if (IS_ERR(wtbl_hdr))
return PTR_ERR(wtbl_hdr);
mt7915_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_hdr);
ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
if (ret)
return ret;
return mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, NULL,
RATE_PARAM_MMPS_UPDATE);
}
static int
mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
struct ieee80211_vif *vif,
@ -2278,7 +2305,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
int ret;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT7915_STA_UPDATE_MAX_SIZE);
MT76_CONNAC_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
@ -2323,7 +2350,7 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
u8 rsv1[8];
} __packed req = {
.action = cpu_to_le32(MT_STA_BSS_GROUP),
.val = cpu_to_le32(mvif->idx % 16),
.val = cpu_to_le32(mvif->mt76.idx % 16),
};
msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
@ -2345,7 +2372,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
MT7915_STA_UPDATE_MAX_SIZE);
MT76_CONNAC_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
@ -2389,53 +2416,6 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
struct ieee80211_sta *sta, u32 rate)
{
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct mt7915_vif *mvif = msta->vif;
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;
if (!rate) {
ra->field = cpu_to_le32(RATE_PARAM_AUTO);
goto out;
}
ra->field = cpu_to_le32(RATE_PARAM_FIXED);
ra->phy.type = FIELD_GET(RATE_CFG_PHY_TYPE, rate);
ra->phy.bw = FIELD_GET(RATE_CFG_BW, rate);
ra->phy.nss = FIELD_GET(RATE_CFG_NSS, rate);
ra->phy.mcs = FIELD_GET(RATE_CFG_MCS, rate);
ra->phy.stbc = FIELD_GET(RATE_CFG_STBC, rate);
if (ra->phy.bw)
ra->phy.ldpc = 7;
else
ra->phy.ldpc = FIELD_GET(RATE_CFG_LDPC, rate) * 7;
/* HT/VHT - SGI: 1, LGI: 0; HE - SGI: 0, MGI: 1, LGI: 2 */
if (ra->phy.type > MT_PHY_TYPE_VHT) {
ra->phy.he_ltf = FIELD_GET(RATE_CFG_HE_LTF, rate) * 85;
ra->phy.sgi = FIELD_GET(RATE_CFG_GI, rate) * 85;
} else {
ra->phy.sgi = FIELD_GET(RATE_CFG_GI, rate) * 15;
}
out:
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
int mt7915_mcu_add_dev_info(struct mt7915_phy *phy,
struct ieee80211_vif *vif, bool enable)
{
@ -2458,8 +2438,8 @@ int mt7915_mcu_add_dev_info(struct mt7915_phy *phy,
} __packed tlv;
} data = {
.hdr = {
.omac_idx = mvif->omac_idx,
.dbdc_idx = mvif->band_idx,
.omac_idx = mvif->mt76.omac_idx,
.dbdc_idx = mvif->mt76.band_idx,
.tlv_num = cpu_to_le16(1),
.is_tlv_append = 1,
},
@ -2467,11 +2447,11 @@ int mt7915_mcu_add_dev_info(struct mt7915_phy *phy,
.tag = cpu_to_le16(DEV_INFO_ACTIVE),
.len = cpu_to_le16(sizeof(struct req_tlv)),
.active = enable,
.dbdc_idx = mvif->band_idx,
.dbdc_idx = mvif->mt76.band_idx,
},
};
if (mvif->omac_idx >= REPEATER_BSSID_START)
if (mvif->mt76.omac_idx >= REPEATER_BSSID_START)
return mt7915_mcu_muar_config(phy, vif, false, enable);
memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN);
@ -2643,7 +2623,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw,
return -EINVAL;
}
if (mvif->band_idx) {
if (mvif->mt76.band_idx) {
info = IEEE80211_SKB_CB(skb);
info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY;
}
@ -2967,7 +2947,7 @@ static int mt7915_load_firmware(struct mt7915_dev *dev)
if (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,
FIELD_PREP(MT_TOP_MISC_FW_STATE,
FW_STATE_WACPU_RDY), 1000)) {
FW_STATE_RDY), 1000)) {
dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
return -EIO;
}
@ -3014,6 +2994,47 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level)
sizeof(data), false);
}
int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enabled)
{
struct {
__le32 cmd;
u8 enable;
} data = {
.cmd = cpu_to_le32(MURU_SET_TXC_TX_STATS_EN),
.enable = enabled,
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL), &data,
sizeof(data), false);
}
int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms)
{
struct mt7915_dev *dev = phy->dev;
struct sk_buff *skb;
struct mt7915_mcu_muru_stats *mu_stats =
(struct mt7915_mcu_muru_stats *)ms;
int ret;
struct {
__le32 cmd;
u8 band_idx;
} req = {
.cmd = cpu_to_le32(MURU_GET_TXC_TX_STATS),
.band_idx = phy != &dev->phy,
};
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(MURU_CTRL),
&req, sizeof(req), true, &skb);
if (ret)
return ret;
memcpy(mu_stats, skb->data, sizeof(struct mt7915_mcu_muru_stats));
dev_kfree_skb(skb);
return 0;
}
static int mt7915_mcu_set_mwds(struct mt7915_dev *dev, bool enabled)
{
struct {
@ -3264,7 +3285,7 @@ int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif)
struct edca *e = &req.edca[ac];
e->set = WMM_PARAM_SET;
e->queue = ac + mvif->wmm_idx * MT7915_MAX_WMM_SETS;
e->queue = ac + mvif->mt76.wmm_idx * MT7915_MAX_WMM_SETS;
e->aifs = q->aifs;
e->txop = cpu_to_le16(q->txop);
@ -3579,6 +3600,30 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
return 0;
}
int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num)
{
struct {
u8 _rsv;
u8 version;
u8 die_idx;
u8 _rsv2;
} __packed req = {
.version = 1,
};
struct sk_buff *skb;
int ret;
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_FREE_BLOCK), &req,
sizeof(req), true, &skb);
if (ret)
return ret;
*block_num = *(u8 *)skb->data;
dev_kfree_skb(skb);
return 0;
}
static int mt7915_mcu_set_pre_cal(struct mt7915_dev *dev, u8 idx,
u8 *data, u32 len, int cmd)
{
@ -3854,11 +3899,11 @@ int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy)
struct mt76_power_limits limits_array;
s8 *la = (s8 *)&limits_array;
int i, idx, n_chains = hweight8(mphy->antenna_mask);
int tx_power;
tx_power = hw->conf.power_level * 2 -
mt76_tx_power_nss_delta(n_chains);
int tx_power = hw->conf.power_level * 2;
tx_power = mt76_get_sar_power(mphy, mphy->chandef.chan,
tx_power);
tx_power -= mt76_tx_power_nss_delta(n_chains);
tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
&limits_array, tx_power);
mphy->txpower_cur = tx_power;
@ -4045,7 +4090,7 @@ int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
} __packed req = {
.action = MT_SPR_ENABLE,
.arg_num = 1,
.band_idx = mvif->band_idx,
.band_idx = mvif->mt76.band_idx,
.val = cpu_to_le32(enable),
};
@ -4066,7 +4111,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
__le16 wcid;
} __packed req = {
.category = MCU_PHY_STATE_CONTENTION_RX_RATE,
.band = mvif->band_idx,
.band = mvif->mt76.band_idx,
.wcid = cpu_to_le16(msta->wcid.idx),
};
struct ieee80211_supported_band *sband;
@ -4206,11 +4251,11 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev,
} __packed req = {
.tbl_idx = flow->table_id,
.cmd = cmd,
.own_mac_idx = mvif->omac_idx,
.own_mac_idx = mvif->mt76.omac_idx,
.flowid = flow->id,
.peer_id = cpu_to_le16(flow->wcid),
.duration = flow->duration,
.bss_idx = mvif->idx,
.bss_idx = mvif->mt76.idx,
.start_tsf = cpu_to_le64(flow->tsf),
.mantissa = flow->mantissa,
.exponent = flow->exp,

View file

@ -4,6 +4,8 @@
#ifndef __MT7915_MCU_H
#define __MT7915_MCU_H
#include "../mt76_connac_mcu.h"
struct mt7915_mcu_txd {
__le32 txd[8];
@ -23,29 +25,6 @@ struct mt7915_mcu_txd {
u32 reserved[5];
} __packed __aligned(4);
/* event table */
enum {
MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
MCU_EVENT_FW_START = 0x01,
MCU_EVENT_GENERIC = 0x01,
MCU_EVENT_ACCESS_REG = 0x02,
MCU_EVENT_MT_PATCH_SEM = 0x04,
MCU_EVENT_CH_PRIVILEGE = 0x18,
MCU_EVENT_EXT = 0xed,
MCU_EVENT_RESTART_DL = 0xef,
};
/* ext event table */
enum {
MCU_EXT_EVENT_PS_SYNC = 0x5,
MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
MCU_EXT_EVENT_RDD_REPORT = 0x3a,
MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
MCU_EXT_EVENT_BCC_NOTIFY = 0x75,
};
enum {
MCU_ATE_SET_TRX = 0x1,
MCU_ATE_SET_FREQ_OFFSET = 0xa,
@ -206,6 +185,44 @@ struct mt7915_mcu_tx {
struct edca edca[IEEE80211_NUM_ACS];
} __packed;
struct mt7915_mcu_muru_stats {
__le32 event_id;
struct {
__le32 cck_cnt;
__le32 ofdm_cnt;
__le32 htmix_cnt;
__le32 htgf_cnt;
__le32 vht_su_cnt;
__le32 vht_2mu_cnt;
__le32 vht_3mu_cnt;
__le32 vht_4mu_cnt;
__le32 he_su_cnt;
__le32 he_ext_su_cnt;
__le32 he_2ru_cnt;
__le32 he_2mu_cnt;
__le32 he_3ru_cnt;
__le32 he_3mu_cnt;
__le32 he_4ru_cnt;
__le32 he_4mu_cnt;
__le32 he_5to8ru_cnt;
__le32 he_9to16ru_cnt;
__le32 he_gtr16ru_cnt;
} dl;
struct {
__le32 hetrig_su_cnt;
__le32 hetrig_2ru_cnt;
__le32 hetrig_3ru_cnt;
__le32 hetrig_4ru_cnt;
__le32 hetrig_5to8ru_cnt;
__le32 hetrig_9to16ru_cnt;
__le32 hetrig_gtr16ru_cnt;
__le32 hetrig_2mu_cnt;
__le32 hetrig_3mu_cnt;
__le32 hetrig_4mu_cnt;
} ul;
};
#define WMM_AIFS_SET BIT(0)
#define WMM_CW_MIN_SET BIT(1)
#define WMM_CW_MAX_SET BIT(2)
@ -215,84 +232,12 @@ struct mt7915_mcu_tx {
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
#define MCU_PKT_ID 0xa0
enum {
MCU_Q_QUERY,
MCU_Q_SET,
MCU_Q_RESERVED,
MCU_Q_NA
};
enum {
MCU_S2D_H2N,
MCU_S2D_C2N,
MCU_S2D_H2C,
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)
#define __MCU_CMD_FIELD_QUERY BIT(16)
#define __MCU_CMD_FIELD_WA BIT(17)
enum {
MCU_CMD_TARGET_ADDRESS_LEN_REQ = 0x01,
MCU_CMD_FW_START_REQ = 0x02,
MCU_CMD_INIT_ACCESS_REG = 0x3,
MCU_CMD_NIC_POWER_CTRL = 0x4,
MCU_CMD_PATCH_START_REQ = 0x05,
MCU_CMD_PATCH_FINISH_REQ = 0x07,
MCU_CMD_PATCH_SEM_CONTROL = 0x10,
MCU_CMD_WA_PARAM = 0xC4,
MCU_CMD_EXT_CID = 0xED,
MCU_CMD_FW_SCATTER = 0xEE,
MCU_CMD_RESTART_DL_REQ = 0xEF,
};
enum {
MCU_EXT_CMD_EFUSE_ACCESS = 0x01,
MCU_EXT_CMD_RF_TEST = 0x04,
MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
MCU_EXT_CMD_TXBF_ACTION = 0x1e,
MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
MCU_EXT_CMD_THERMAL_PROT = 0x23,
MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
MCU_EXT_CMD_THERMAL_CTRL = 0x2c,
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
MCU_EXT_CMD_SET_DRR_CTRL = 0x36,
MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
MCU_EXT_CMD_ATE_CTRL = 0x3d,
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
MCU_EXT_CMD_RX_HDR_TRANS = 0x47,
MCU_EXT_CMD_MUAR_UPDATE = 0x48,
MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a,
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
MCU_EXT_CMD_MWDS_SUPPORT = 0x80,
MCU_EXT_CMD_SET_SER_TRIGGER = 0x81,
MCU_EXT_CMD_SCS_CTRL = 0x82,
MCU_EXT_CMD_TWT_AGRT_UPDATE = 0x94,
MCU_EXT_CMD_FW_DBG_CTRL = 0x95,
MCU_EXT_CMD_SET_RDD_TH = 0x9d,
MCU_EXT_CMD_MURU_CTRL = 0x9f,
MCU_EXT_CMD_SET_SPR = 0xa8,
MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab,
MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac,
MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
};
enum {
MCU_TWT_AGRT_ADD,
MCU_TWT_AGRT_MODIFY,
@ -314,55 +259,11 @@ enum {
MCU_WA_PARAM_RED = 0x0e,
};
#define MCU_CMD(_t) FIELD_PREP(__MCU_CMD_FIELD_ID, MCU_CMD_##_t)
#define MCU_EXT_CMD(_t) (MCU_CMD(EXT_CID) | \
FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \
MCU_EXT_CMD_##_t))
#define MCU_EXT_QUERY(_t) (MCU_EXT_CMD(_t) | __MCU_CMD_FIELD_QUERY)
#define MCU_WA_CMD(_t) (MCU_CMD(_t) | __MCU_CMD_FIELD_WA)
#define MCU_WA_EXT_CMD(_t) (MCU_EXT_CMD(_t) | __MCU_CMD_FIELD_WA)
#define MCU_WA_PARAM_CMD(_t) (MCU_WA_CMD(WA_PARAM) | \
FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \
MCU_WA_PARAM_CMD_##_t))
enum {
PATCH_SEM_RELEASE,
PATCH_SEM_GET
};
enum {
PATCH_NOT_DL_SEM_FAIL,
PATCH_IS_DL,
PATCH_NOT_DL_SEM_SUCCESS,
PATCH_REL_SEM_SUCCESS
};
enum {
FW_STATE_INITIAL,
FW_STATE_FW_DOWNLOAD,
FW_STATE_NORMAL_OPERATION,
FW_STATE_NORMAL_TRX,
FW_STATE_WACPU_RDY = 7
};
enum {
EE_MODE_EFUSE,
EE_MODE_BUFFER,
};
enum {
EE_FORMAT_BIN,
EE_FORMAT_WHOLE,
EE_FORMAT_MULTIPLE,
};
enum {
MCU_PHY_STATE_TX_RATE,
MCU_PHY_STATE_RX_RATE,
MCU_PHY_STATE_RSSI,
MCU_PHY_STATE_CONTENTION_RX_RATE,
MCU_PHY_STATE_OFDMLQ_CNINFO,
enum mcu_mmps_mode {
MCU_MMPS_STATIC,
MCU_MMPS_DYNAMIC,
MCU_MMPS_RSV,
MCU_MMPS_DISABLE,
};
#define STA_TYPE_STA BIT(0)
@ -388,11 +289,6 @@ enum {
#define CONN_STATE_CONNECT 1
#define CONN_STATE_PORT_SECURE 2
enum {
DEV_INFO_ACTIVE,
DEV_INFO_MAX_NUM
};
enum {
SCS_SEND_DATA,
SCS_SET_MANUAL_PD_TH,
@ -403,75 +299,6 @@ enum {
SCS_GET_GLO_ADDR_EVENT,
};
enum {
CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20,
CMD_CBW_40MHZ = IEEE80211_STA_RX_BW_40,
CMD_CBW_80MHZ = IEEE80211_STA_RX_BW_80,
CMD_CBW_160MHZ = IEEE80211_STA_RX_BW_160,
CMD_CBW_10MHZ,
CMD_CBW_5MHZ,
CMD_CBW_8080MHZ,
CMD_HE_MCS_BW80 = 0,
CMD_HE_MCS_BW160,
CMD_HE_MCS_BW8080,
CMD_HE_MCS_BW_NUM
};
struct tlv {
__le16 tag;
__le16 len;
} __packed;
struct bss_info_omac {
__le16 tag;
__le16 len;
u8 hw_bss_idx;
u8 omac_idx;
u8 band_idx;
u8 rsv0;
__le32 conn_type;
u32 rsv1;
} __packed;
struct bss_info_basic {
__le16 tag;
__le16 len;
__le32 network_type;
u8 active;
u8 rsv0;
__le16 bcn_interval;
u8 bssid[ETH_ALEN];
u8 wmm_idx;
u8 dtim_period;
u8 bmc_wcid_lo;
u8 cipher;
u8 phy_mode;
u8 max_bssid; /* max BSSID. range: 1 ~ 8, 0: MBSSID disabled */
u8 non_tx_bssid;/* non-transmitted BSSID, 0: transmitted BSSID */
u8 bmc_wcid_hi; /* high Byte and version */
u8 rsv[2];
} __packed;
struct bss_info_rf_ch {
__le16 tag;
__le16 len;
u8 pri_ch;
u8 center_ch0;
u8 center_ch1;
u8 bw;
u8 he_ru26_block; /* 1: don't send HETB in RU26, 0: allow */
u8 he_all_disable; /* 1: disallow all HETB, 0: allow */
u8 rsv[2];
} __packed;
struct bss_info_ext_bss {
__le16 tag;
__le16 len;
__le32 mbss_tsf_offset; /* in unit of us */
u8 rsv[8];
} __packed;
struct bss_info_bmc_rate {
__le16 tag;
__le16 len;
@ -580,386 +407,9 @@ enum {
BSS_INFO_BCN_MAX
};
enum {
BSS_INFO_OMAC,
BSS_INFO_BASIC,
BSS_INFO_RF_CH, /* optional, for BT/LTE coex */
BSS_INFO_PM, /* sta only */
BSS_INFO_UAPSD, /* sta only */
BSS_INFO_ROAM_DETECT, /* obsoleted */
BSS_INFO_LQ_RM, /* obsoleted */
BSS_INFO_EXT_BSS,
BSS_INFO_BMC_RATE, /* for bmc rate control in CR4 */
BSS_INFO_SYNC_MODE, /* obsoleted */
BSS_INFO_RA,
BSS_INFO_HW_AMSDU,
BSS_INFO_BSS_COLOR,
BSS_INFO_HE_BASIC,
BSS_INFO_PROTECT_INFO,
BSS_INFO_OFFLOAD,
BSS_INFO_11V_MBSSID,
BSS_INFO_MAX_NUM
};
enum {
WTBL_RESET_AND_SET = 1,
WTBL_SET,
WTBL_QUERY,
WTBL_RESET_ALL
};
struct wtbl_req_hdr {
u8 wlan_idx_lo;
u8 operation;
__le16 tlv_num;
u8 wlan_idx_hi;
u8 rsv[3];
} __packed;
struct wtbl_generic {
__le16 tag;
__le16 len;
u8 peer_addr[ETH_ALEN];
u8 muar_idx;
u8 skip_tx;
u8 cf_ack;
u8 qos;
u8 mesh;
u8 adm;
__le16 partial_aid;
u8 baf_en;
u8 aad_om;
} __packed;
struct wtbl_rx {
__le16 tag;
__le16 len;
u8 rcid;
u8 rca1;
u8 rca2;
u8 rv;
u8 rsv[4];
} __packed;
struct wtbl_ht {
__le16 tag;
__le16 len;
u8 ht;
u8 ldpc;
u8 af;
u8 mm;
u8 rsv[4];
} __packed;
struct wtbl_vht {
__le16 tag;
__le16 len;
u8 ldpc;
u8 dyn_bw;
u8 vht;
u8 txop_ps;
u8 rsv[4];
} __packed;
struct wtbl_hdr_trans {
__le16 tag;
__le16 len;
u8 to_ds;
u8 from_ds;
u8 no_rx_trans;
u8 _rsv;
};
enum {
MT_BA_TYPE_INVALID,
MT_BA_TYPE_ORIGINATOR,
MT_BA_TYPE_RECIPIENT
};
enum {
RST_BA_MAC_TID_MATCH,
RST_BA_MAC_MATCH,
RST_BA_NO_MATCH
};
struct wtbl_ba {
__le16 tag;
__le16 len;
/* common */
u8 tid;
u8 ba_type;
u8 rsv0[2];
/* originator only */
__le16 sn;
u8 ba_en;
u8 ba_winsize_idx;
/* originator & recipient */
__le16 ba_winsize;
/* recipient only */
u8 peer_addr[ETH_ALEN];
u8 rst_ba_tid;
u8 rst_ba_sel;
u8 rst_ba_sb;
u8 band_idx;
u8 rsv1[4];
} __packed;
struct wtbl_smps {
__le16 tag;
__le16 len;
u8 smps;
u8 rsv[3];
} __packed;
enum {
WTBL_GENERIC,
WTBL_RX,
WTBL_HT,
WTBL_VHT,
WTBL_PEER_PS, /* not used */
WTBL_TX_PS,
WTBL_HDR_TRANS,
WTBL_SEC_KEY,
WTBL_BA,
WTBL_RDG, /* obsoleted */
WTBL_PROTECT, /* not used */
WTBL_CLEAR, /* not used */
WTBL_BF,
WTBL_SMPS,
WTBL_RAW_DATA, /* debug only */
WTBL_PN,
WTBL_SPE,
WTBL_MAX_NUM
};
struct sta_ntlv_hdr {
u8 rsv[2];
__le16 tlv_num;
} __packed;
struct sta_req_hdr {
u8 bss_idx;
u8 wlan_idx_lo;
__le16 tlv_num;
u8 is_tlv_append;
u8 muar_idx;
u8 wlan_idx_hi;
u8 rsv;
} __packed;
struct sta_rec_basic {
__le16 tag;
__le16 len;
__le32 conn_type;
u8 conn_state;
u8 qos;
__le16 aid;
u8 peer_addr[ETH_ALEN];
__le16 extra_info;
} __packed;
struct sta_rec_ht {
__le16 tag;
__le16 len;
__le16 ht_cap;
u16 rsv;
} __packed;
struct sta_rec_vht {
__le16 tag;
__le16 len;
__le32 vht_cap;
__le16 vht_rx_mcs_map;
__le16 vht_tx_mcs_map;
u8 rts_bw_sig;
u8 rsv[3];
} __packed;
struct sta_rec_uapsd {
__le16 tag;
__le16 len;
u8 dac_map;
u8 tac_map;
u8 max_sp;
u8 rsv0;
__le16 listen_interval;
u8 rsv1[2];
} __packed;
struct sta_rec_muru {
__le16 tag;
__le16 len;
struct {
bool ofdma_dl_en;
bool ofdma_ul_en;
bool mimo_dl_en;
bool mimo_ul_en;
u8 rsv[4];
} cfg;
struct {
u8 punc_pream_rx;
bool he_20m_in_40m_2g;
bool he_20m_in_160m;
bool he_80m_in_160m;
bool lt16_sigb;
bool rx_su_comp_sigb;
bool rx_su_non_comp_sigb;
u8 rsv;
} ofdma_dl;
struct {
u8 t_frame_dur;
u8 mu_cascading;
u8 uo_ra;
u8 he_2x996_tone;
u8 rx_t_frame_11ac;
u8 rsv[3];
} ofdma_ul;
struct {
bool vht_mu_bfee;
bool partial_bw_dl_mimo;
u8 rsv[2];
} mimo_dl;
struct {
bool full_ul_mimo;
bool partial_ul_mimo;
u8 rsv[2];
} mimo_ul;
} __packed;
struct sta_rec_he {
__le16 tag;
__le16 len;
__le32 he_cap;
u8 t_frame_dur;
u8 max_ampdu_exp;
u8 bw_set;
u8 device_class;
u8 dcm_tx_mode;
u8 dcm_tx_max_nss;
u8 dcm_rx_mode;
u8 dcm_rx_max_nss;
u8 dcm_max_ru;
u8 punc_pream_rx;
u8 pkt_ext;
u8 rsv1;
__le16 max_nss_mcs[CMD_HE_MCS_BW_NUM];
u8 rsv2[2];
} __packed;
struct sta_rec_ba {
__le16 tag;
__le16 len;
u8 tid;
u8 ba_type;
u8 amsdu;
u8 ba_en;
__le16 ssn;
__le16 winsize;
} __packed;
struct sta_rec_amsdu {
__le16 tag;
__le16 len;
u8 max_amsdu_num;
u8 max_mpdu_size;
u8 amsdu_en;
u8 rsv;
} __packed;
struct sec_key {
u8 cipher_id;
u8 cipher_len;
u8 key_id;
u8 key_len;
u8 key[32];
} __packed;
struct sta_rec_sec {
__le16 tag;
__le16 len;
u8 add;
u8 n_cipher;
u8 rsv[2];
struct sec_key key[2];
} __packed;
struct sta_phy {
u8 type;
u8 flag;
u8 stbc;
u8 sgi;
u8 bw;
u8 ldpc;
u8 mcs;
u8 nss;
u8 he_ltf;
};
struct sta_rec_ra {
__le16 tag;
__le16 len;
u8 valid;
u8 auto_rate;
u8 phy_mode;
u8 channel;
u8 bw;
u8 disable_cck;
u8 ht_mcs32;
u8 ht_gf;
u8 ht_mcs[4];
u8 mmps_mode;
u8 gband_256;
u8 af;
u8 auth_wapi_mode;
u8 rate_len;
u8 supp_mode;
u8 supp_cck_rate;
u8 supp_ofdm_rate;
__le32 supp_ht_mcs;
__le16 supp_vht_mcs[4];
u8 op_mode;
u8 op_vht_chan_width;
u8 op_vht_rx_nss;
u8 op_vht_rx_nss_type;
__le32 sta_cap;
struct sta_phy phy;
} __packed;
struct sta_rec_ra_fixed {
__le16 tag;
__le16 len;
__le32 field;
u8 op_mode;
u8 op_vht_chan_width;
u8 op_vht_rx_nss;
u8 op_vht_rx_nss_type;
struct sta_phy phy;
u8 spe_en;
u8 short_preamble;
u8 is_5g;
u8 mmps_mode;
} __packed;
enum {
RATE_PARAM_FIXED = 3,
RATE_PARAM_MMPS_UPDATE = 5,
RATE_PARAM_FIXED_HE_LTF = 7,
RATE_PARAM_FIXED_MCS,
RATE_PARAM_FIXED_GI = 11,
@ -975,120 +425,6 @@ enum {
#define RATE_CFG_PHY_TYPE GENMASK(27, 24)
#define RATE_CFG_HE_LTF GENMASK(31, 28)
struct sta_rec_bf {
__le16 tag;
__le16 len;
__le16 pfmu; /* 0xffff: no access right for PFMU */
bool su_mu; /* 0: SU, 1: MU */
u8 bf_cap; /* 0: iBF, 1: eBF */
u8 sounding_phy; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT */
u8 ndpa_rate;
u8 ndp_rate;
u8 rept_poll_rate;
u8 tx_mode; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT ... */
u8 ncol;
u8 nrow;
u8 bw; /* 0: 20M, 1: 40M, 2: 80M, 3: 160M */
u8 mem_total;
u8 mem_20m;
struct {
u8 row;
u8 col: 6, row_msb: 2;
} mem[4];
__le16 smart_ant;
u8 se_idx;
u8 auto_sounding; /* b7: low traffic indicator
* b6: Stop sounding for this entry
* b5 ~ b0: postpone sounding
*/
u8 ibf_timeout;
u8 ibf_dbw;
u8 ibf_ncol;
u8 ibf_nrow;
u8 nrow_bw160;
u8 ncol_bw160;
u8 ru_start_idx;
u8 ru_end_idx;
bool trigger_su;
bool trigger_mu;
bool ng16_su;
bool ng16_mu;
bool codebook42_su;
bool codebook75_mu;
u8 he_ltf;
u8 rsv[3];
} __packed;
struct sta_rec_bfee {
__le16 tag;
__le16 len;
bool fb_identity_matrix; /* 1: feedback identity matrix */
bool ignore_feedback; /* 1: ignore */
u8 rsv[2];
} __packed;
enum {
STA_REC_BASIC,
STA_REC_RA,
STA_REC_RA_CMM_INFO,
STA_REC_RA_UPDATE,
STA_REC_BF,
STA_REC_AMSDU,
STA_REC_BA,
STA_REC_RED, /* not used */
STA_REC_TX_PROC, /* for hdr trans and CSO in CR4 */
STA_REC_HT,
STA_REC_VHT,
STA_REC_APPS,
STA_REC_KEY,
STA_REC_WTBL,
STA_REC_HE,
STA_REC_HW_AMSDU,
STA_REC_WTBL_AADOM,
STA_REC_KEY_V2,
STA_REC_MURU,
STA_REC_MUEDCA,
STA_REC_BFEE,
STA_REC_MAX_NUM
};
enum mcu_cipher_type {
MCU_CIPHER_NONE = 0,
MCU_CIPHER_WEP40,
MCU_CIPHER_WEP104,
MCU_CIPHER_WEP128,
MCU_CIPHER_TKIP,
MCU_CIPHER_AES_CCMP,
MCU_CIPHER_CCMP_256,
MCU_CIPHER_GCMP,
MCU_CIPHER_GCMP_256,
MCU_CIPHER_WAPI,
MCU_CIPHER_BIP_CMAC_128,
};
enum {
CH_SWITCH_NORMAL = 0,
CH_SWITCH_SCAN = 3,
CH_SWITCH_MCC = 4,
CH_SWITCH_DFS = 5,
CH_SWITCH_BACKGROUND_SCAN_START = 6,
CH_SWITCH_BACKGROUND_SCAN_RUNNING = 7,
CH_SWITCH_BACKGROUND_SCAN_STOP = 8,
CH_SWITCH_SCAN_BYPASS_DPD = 9
};
enum {
THERMAL_SENSOR_TEMP_QUERY,
THERMAL_SENSOR_MANUAL_CTRL,
THERMAL_SENSOR_INFO_QUERY,
THERMAL_SENSOR_TASK_CTRL,
};
enum {
THERMAL_PROTECT_PARAMETER_CTRL,
THERMAL_PROTECT_BASIC_INFO,
@ -1116,28 +452,11 @@ enum {
MURU_PLATFORM_TYPE_PERF_LEVEL_2,
};
#define MT7915_WTBL_UPDATE_MAX_SIZE (sizeof(struct wtbl_req_hdr) + \
sizeof(struct wtbl_generic) + \
sizeof(struct wtbl_rx) + \
sizeof(struct wtbl_ht) + \
sizeof(struct wtbl_vht) + \
sizeof(struct wtbl_hdr_trans) +\
sizeof(struct wtbl_ba) + \
sizeof(struct wtbl_smps))
#define MT7915_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
sizeof(struct sta_rec_basic) + \
sizeof(struct sta_rec_bf) + \
sizeof(struct sta_rec_ht) + \
sizeof(struct sta_rec_he) + \
sizeof(struct sta_rec_ba) + \
sizeof(struct sta_rec_vht) + \
sizeof(struct sta_rec_uapsd) + \
sizeof(struct sta_rec_amsdu) + \
sizeof(struct sta_rec_muru) + \
sizeof(struct sta_rec_bfee) + \
sizeof(struct tlv) + \
MT7915_WTBL_UPDATE_MAX_SIZE)
/* tx cmd tx statistics */
enum {
MURU_SET_TXC_TX_STATS_EN = 150,
MURU_GET_TXC_TX_STATS = 151,
};
#define MT7915_BSS_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
sizeof(struct bss_info_omac) + \
@ -1154,62 +473,4 @@ enum {
sizeof(struct bss_info_bcn_mbss) + \
sizeof(struct bss_info_bcn_cont))
#define PHY_MODE_A BIT(0)
#define PHY_MODE_B BIT(1)
#define PHY_MODE_G BIT(2)
#define PHY_MODE_GN BIT(3)
#define PHY_MODE_AN BIT(4)
#define PHY_MODE_AC BIT(5)
#define PHY_MODE_AX_24G BIT(6)
#define PHY_MODE_AX_5G BIT(7)
#define PHY_MODE_AX_6G BIT(8)
#define MODE_CCK BIT(0)
#define MODE_OFDM BIT(1)
#define MODE_HT BIT(2)
#define MODE_VHT BIT(3)
#define MODE_HE BIT(4)
#define STA_CAP_WMM BIT(0)
#define STA_CAP_SGI_20 BIT(4)
#define STA_CAP_SGI_40 BIT(5)
#define STA_CAP_TX_STBC BIT(6)
#define STA_CAP_RX_STBC BIT(7)
#define STA_CAP_VHT_SGI_80 BIT(16)
#define STA_CAP_VHT_SGI_160 BIT(17)
#define STA_CAP_VHT_TX_STBC BIT(18)
#define STA_CAP_VHT_RX_STBC BIT(19)
#define STA_CAP_VHT_LDPC BIT(23)
#define STA_CAP_LDPC BIT(24)
#define STA_CAP_HT BIT(26)
#define STA_CAP_VHT BIT(27)
#define STA_CAP_HE BIT(28)
/* HE MAC */
#define STA_REC_HE_CAP_HTC BIT(0)
#define STA_REC_HE_CAP_BQR BIT(1)
#define STA_REC_HE_CAP_BSR BIT(2)
#define STA_REC_HE_CAP_OM BIT(3)
#define STA_REC_HE_CAP_AMSDU_IN_AMPDU BIT(4)
/* HE PHY */
#define STA_REC_HE_CAP_DUAL_BAND BIT(5)
#define STA_REC_HE_CAP_LDPC BIT(6)
#define STA_REC_HE_CAP_TRIG_CQI_FK BIT(7)
#define STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE BIT(8)
/* STBC */
#define STA_REC_HE_CAP_LE_EQ_80M_TX_STBC BIT(9)
#define STA_REC_HE_CAP_LE_EQ_80M_RX_STBC BIT(10)
#define STA_REC_HE_CAP_GT_80M_TX_STBC BIT(11)
#define STA_REC_HE_CAP_GT_80M_RX_STBC BIT(12)
/* GI */
#define STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI BIT(13)
#define STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI BIT(14)
#define STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI BIT(15)
#define STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI BIT(16)
#define STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI BIT(17)
/* 242 TONE */
#define STA_REC_HE_CAP_BW20_RU242_SUPPORT BIT(18)
#define STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242 BIT(19)
#define STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242 BIT(20)
#endif

View file

@ -30,6 +30,9 @@
#define MT7915_FIRMWARE_WM "mediatek/mt7915_wm.bin"
#define MT7915_ROM_PATCH "mediatek/mt7915_rom_patch.bin"
#define MT7915_EEPROM_DEFAULT "mediatek/mt7915_eeprom.bin"
#define MT7915_EEPROM_DEFAULT_DBDC "mediatek/mt7915_eeprom_dbdc.bin"
#define MT7915_EEPROM_SIZE 3584
#define MT7915_EEPROM_BLOCK_SIZE 16
#define MT7915_TOKEN_SIZE 8192
@ -121,10 +124,7 @@ struct mt7915_vif_cap {
};
struct mt7915_vif {
u16 idx;
u8 omac_idx;
u8 band_idx;
u8 wmm_idx;
struct mt76_vif mt76; /* must be first */
struct mt7915_vif_cap cap;
struct mt7915_sta sta;
@ -270,6 +270,7 @@ struct mt7915_dev {
bool dbdc_support;
bool flash_mode;
bool muru_debug;
bool ibf;
u8 fw_debug_wm;
u8 fw_debug_wa;
@ -282,20 +283,6 @@ struct mt7915_dev {
} twt;
};
enum {
HW_BSSID_0 = 0x0,
HW_BSSID_1,
HW_BSSID_2,
HW_BSSID_3,
HW_BSSID_MAX = HW_BSSID_3,
EXT_BSSID_START = 0x10,
EXT_BSSID_1,
EXT_BSSID_15 = 0x1f,
EXT_BSSID_MAX = EXT_BSSID_15,
REPEATER_BSSID_START = 0x20,
REPEATER_BSSID_MAX = 0x3f,
};
enum {
MT_CTX0,
MT_HIF0 = 0x0,
@ -423,6 +410,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
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_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num);
int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
bool hdr_trans);
int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
@ -515,6 +503,7 @@ void mt7915_tx_token_put(struct mt7915_dev *dev);
int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc);
void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb);
bool mt7915_rx_check(struct mt76_dev *mdev, void *data, int len);
void mt7915_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);
void mt7915_stats_work(struct work_struct *work);
int mt76_dfs_start_rdd(struct mt7915_dev *dev, bool force);
@ -522,6 +511,8 @@ int mt7915_dfs_init_radar_detector(struct mt7915_phy *phy);
void mt7915_set_stream_he_caps(struct mt7915_phy *phy);
void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy);
void mt7915_update_channel(struct mt76_phy *mphy);
int mt7915_mcu_muru_debug_set(struct mt7915_dev *dev, bool enable);
int mt7915_mcu_muru_debug_get(struct mt7915_phy *phy, void *ms);
int mt7915_init_debugfs(struct mt7915_phy *phy);
#ifdef CONFIG_MAC80211_DEBUGFS
void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,

View file

@ -230,6 +230,7 @@ static int mt7915_pci_probe(struct pci_dev *pdev,
.tx_prepare_skb = mt7915_tx_prepare_skb,
.tx_complete_skb = mt7915_tx_complete_skb,
.rx_skb = mt7915_queue_rx_skb,
.rx_check = mt7915_rx_check,
.rx_poll_complete = mt7915_rx_poll_complete,
.sta_ps = mt7915_sta_ps,
.sta_add = mt7915_mac_sta_add,

View file

@ -361,16 +361,15 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
return;
}
if (b)
return;
if (!b) {
b = devm_kzalloc(dev->mt76.dev, 4 * n_regs, GFP_KERNEL);
if (!b)
return;
b = devm_kzalloc(dev->mt76.dev, 4 * n_regs, GFP_KERNEL);
if (!b)
return;
phy->test.reg_backup = b;
for (i = 0; i < n_regs; i++)
b[i] = mt76_rr(dev, reg_backup_list[i].band[ext_phy]);
phy->test.reg_backup = b;
for (i = 0; i < n_regs; i++)
b[i] = mt76_rr(dev, reg_backup_list[i].band[ext_phy]);
}
mt76_clear(dev, MT_AGG_PCR0(ext_phy, 0), MT_AGG_PCR0_MM_PROT |
MT_AGG_PCR0_GF_PROT | MT_AGG_PCR0_ERP_PROT |

View file

@ -76,14 +76,6 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
wiphy->max_sched_scan_reqs = 1;
wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
wiphy->reg_notifier = mt7921_regd_notifier;
wiphy->sar_capa = &mt76_sar_capa;
phy->mt76->frp = devm_kcalloc(dev->mt76.dev,
wiphy->sar_capa->num_freq_ranges,
sizeof(struct mt76_freq_range_power),
GFP_KERNEL);
if (!phy->mt76->frp)
return -ENOMEM;
wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
@ -264,6 +256,10 @@ int mt7921_register_device(struct mt7921_dev *dev)
IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
(3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
if (is_mt7922(&dev->mt76))
dev->mphy.sband_5g.sband.vht_cap.cap |=
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
IEEE80211_VHT_CAP_SHORT_GI_160;
dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;
dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;

View file

@ -218,10 +218,9 @@ mt7921_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
}
static void
mt7921_mac_decode_he_mu_radiotap(struct sk_buff *skb,
struct mt76_rx_status *status,
__le32 *rxv)
mt7921_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
static const struct ieee80211_radiotap_he_mu mu_known = {
.flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
@ -233,6 +232,8 @@ mt7921_mac_decode_he_mu_radiotap(struct sk_buff *skb,
};
struct ieee80211_radiotap_he_mu *he_mu;
status->flag |= RX_FLAG_RADIOTAP_HE_MU;
he_mu = skb_push(skb, sizeof(mu_known));
memcpy(he_mu, &mu_known, sizeof(mu_known));
@ -263,10 +264,9 @@ mt7921_mac_decode_he_mu_radiotap(struct sk_buff *skb,
}
static void
mt7921_mac_decode_he_radiotap(struct sk_buff *skb,
struct mt76_rx_status *status,
__le32 *rxv, u32 phy)
mt7921_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u32 mode)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
static const struct ieee80211_radiotap_he known = {
.data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
HE_BITS(DATA1_DATA_DCM_KNOWN) |
@ -284,6 +284,8 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb,
struct ieee80211_radiotap_he *he = NULL;
u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1;
status->flag |= RX_FLAG_RADIOTAP_HE;
he = skb_push(skb, sizeof(known));
memcpy(he, &known, sizeof(known));
@ -298,7 +300,7 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb,
he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) |
HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]);
switch (phy) {
switch (mode) {
case MT_PHY_TYPE_HE_SU:
he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
HE_BITS(DATA1_UL_DL_KNOWN) |
@ -322,6 +324,7 @@ mt7921_mac_decode_he_radiotap(struct sk_buff *skb,
he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]);
mt7921_mac_decode_he_radiotap_ru(status, he, rxv);
mt7921_mac_decode_he_mu_radiotap(skb, rxv);
break;
case MT_PHY_TYPE_HE_TB:
he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
@ -395,6 +398,81 @@ mt7921_mac_assoc_rssi(struct mt7921_dev *dev, struct sk_buff *skb)
mt7921_mac_rssi_iter, skb);
}
/* The HW does not translate the mac header to 802.3 for mesh point */
static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
struct mt7921_sta *msta = (struct mt7921_sta *)status->wcid;
struct ieee80211_sta *sta;
struct ieee80211_vif *vif;
struct ieee80211_hdr hdr;
struct ethhdr eth_hdr;
__le32 *rxd = (__le32 *)skb->data;
__le32 qos_ctrl, ht_ctrl;
if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) !=
MT_RXD3_NORMAL_U2M)
return -EINVAL;
if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4))
return -EINVAL;
if (!msta || !msta->vif)
return -EINVAL;
sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
/* store the info from RXD and ethhdr to avoid being overridden */
memcpy(&eth_hdr, skb->data + hdr_gap, sizeof(eth_hdr));
hdr.frame_control = FIELD_GET(MT_RXD6_FRAME_CONTROL, rxd[6]);
hdr.seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, rxd[8]);
qos_ctrl = FIELD_GET(MT_RXD8_QOS_CTL, rxd[8]);
ht_ctrl = FIELD_GET(MT_RXD9_HT_CONTROL, rxd[9]);
hdr.duration_id = 0;
ether_addr_copy(hdr.addr1, vif->addr);
ether_addr_copy(hdr.addr2, sta->addr);
switch (le16_to_cpu(hdr.frame_control) &
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case 0:
ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
break;
case IEEE80211_FCTL_FROMDS:
ether_addr_copy(hdr.addr3, eth_hdr.h_source);
break;
case IEEE80211_FCTL_TODS:
ether_addr_copy(hdr.addr3, eth_hdr.h_dest);
break;
case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS:
ether_addr_copy(hdr.addr3, eth_hdr.h_dest);
ether_addr_copy(hdr.addr4, eth_hdr.h_source);
break;
default:
break;
}
skb_pull(skb, hdr_gap + sizeof(struct ethhdr) - 2);
if (eth_hdr.h_proto == htons(ETH_P_AARP) ||
eth_hdr.h_proto == htons(ETH_P_IPX))
ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
else if (eth_hdr.h_proto >= htons(ETH_P_802_3_MIN))
ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
else
skb_pull(skb, 2);
if (ieee80211_has_order(hdr.frame_control))
memcpy(skb_push(skb, 2), &ht_ctrl, 2);
if (ieee80211_is_data_qos(hdr.frame_control))
memcpy(skb_push(skb, 2), &qos_ctrl, 2);
if (ieee80211_has_a4(hdr.frame_control))
memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
else
memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6);
return 0;
}
static int
mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
{
@ -402,11 +480,11 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
bool hdr_trans, unicast, insert_ccmp_hdr = false;
u8 chfreq, qos_ctl = 0, remove_pad, amsdu_info;
u16 hdr_gap;
__le32 *rxv = NULL, *rxd = (__le32 *)skb->data;
struct mt76_phy *mphy = &dev->mt76.phy;
struct mt7921_phy *phy = &dev->phy;
struct ieee80211_supported_band *sband;
struct ieee80211_hdr *hdr;
u32 rxd0 = le32_to_cpu(rxd[0]);
u32 rxd1 = le32_to_cpu(rxd[1]);
u32 rxd2 = le32_to_cpu(rxd[2]);
@ -428,10 +506,17 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
return -EINVAL;
hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
return -EINVAL;
/* ICV error or CCMP/BIP/WPI MIC error */
if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
status->flag |= RX_FLAG_ONLY_MONITOR;
chfreq = FIELD_GET(MT_RXD3_NORMAL_CH_FREQ, rxd3);
unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
status->wcid = mt7921_rx_get_wcid(dev, idx, unicast);
if (status->wcid) {
@ -612,15 +697,12 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
return -EINVAL;
break;
case MT_PHY_TYPE_HE_MU:
status->flag |= RX_FLAG_RADIOTAP_HE_MU;
fallthrough;
case MT_PHY_TYPE_HE_SU:
case MT_PHY_TYPE_HE_EXT_SU:
case MT_PHY_TYPE_HE_TB:
status->nss =
FIELD_GET(MT_PRXV_NSTS, v0) + 1;
status->encoding = RX_ENC_HE;
status->flag |= RX_FLAG_RADIOTAP_HE;
i &= GENMASK(3, 0);
if (gi <= NL80211_RATE_INFO_HE_GI_3_2)
@ -668,14 +750,21 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
}
}
skb_pull(skb, (u8 *)rxd - skb->data + 2 * remove_pad);
amsdu_info = FIELD_GET(MT_RXD4_NORMAL_PAYLOAD_FORMAT, rxd4);
status->amsdu = !!amsdu_info;
if (status->amsdu) {
status->first_amsdu = amsdu_info == MT_RXD4_FIRST_AMSDU_FRAME;
status->last_amsdu = amsdu_info == MT_RXD4_LAST_AMSDU_FRAME;
if (!hdr_trans) {
}
hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad;
if (hdr_trans && ieee80211_has_morefrags(fc)) {
if (mt7921_reverse_frag0_hdr_trans(skb, hdr_gap))
return -EINVAL;
hdr_trans = false;
} else {
skb_pull(skb, hdr_gap);
if (!hdr_trans && status->amsdu) {
memmove(skb->data + 2, skb->data,
ieee80211_get_hdrlen_from_skb(skb));
skb_pull(skb, 2);
@ -683,6 +772,8 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
}
if (!hdr_trans) {
struct ieee80211_hdr *hdr;
if (insert_ccmp_hdr) {
u8 key_id = FIELD_GET(MT_RXD1_NORMAL_KEY_ID, rxd1);
@ -696,19 +787,13 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
qos_ctl = *ieee80211_get_qos_ctl(hdr);
}
} else {
status->flag &= ~(RX_FLAG_RADIOTAP_HE |
RX_FLAG_RADIOTAP_HE_MU);
status->flag |= RX_FLAG_8023;
}
mt7921_mac_assoc_rssi(dev, skb);
if (rxv && status->flag & RX_FLAG_RADIOTAP_HE) {
mt7921_mac_decode_he_radiotap(skb, status, rxv, mode);
if (status->flag & RX_FLAG_RADIOTAP_HE_MU)
mt7921_mac_decode_he_mu_radiotap(skb, status, rxv);
}
if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
mt7921_mac_decode_he_radiotap(skb, rxv, mode);
if (!status->wcid || !ieee80211_is_data_qos(fc))
return 0;
@ -903,7 +988,7 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
mt7921_mac_write_txwi_80211(dev, txwi, skb, key);
if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
int rateidx = ffs(vif->bss_conf.basic_rates) - 1;
int rateidx = vif ? ffs(vif->bss_conf.basic_rates) - 1 : 0;
u16 rate, mode;
/* hardware won't add HTC for mgmt/ctrl frame */
@ -1065,7 +1150,7 @@ mt7921_mac_add_txs_skb(struct mt7921_dev *dev, struct mt76_wcid *wcid, int pid,
return !!skb;
}
static void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
{
struct mt7921_sta *msta = NULL;
struct mt76_wcid *wcid;
@ -1314,6 +1399,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
}
dev->hw_full_reset = false;
pm->suspended = false;
ieee80211_wake_queues(hw);
ieee80211_iterate_active_interfaces(hw,
IEEE80211_IFACE_ITER_RESUME_ALL,

View file

@ -128,11 +128,23 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band,
IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
if (is_mt7922(phy->mt76->dev)) {
he_cap_elem->phy_cap_info[0] |=
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
he_cap_elem->phy_cap_info[8] |=
IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU;
}
break;
}
he_mcs->rx_mcs_80 = cpu_to_le16(mcs_map);
he_mcs->tx_mcs_80 = cpu_to_le16(mcs_map);
if (is_mt7922(phy->mt76->dev)) {
he_mcs->rx_mcs_160 = cpu_to_le16(mcs_map);
he_mcs->tx_mcs_160 = cpu_to_le16(mcs_map);
}
memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
if (he_cap_elem->phy_cap_info[6] &
@ -166,7 +178,7 @@ mt7921_init_he_caps(struct mt7921_phy *phy, enum nl80211_band band,
if (vht_cap->cap & IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN)
cap |= IEEE80211_HE_6GHZ_CAP_RX_ANTPAT_CONS;
data->he_6ghz_capa.capa = cpu_to_le16(cap);
data[idx].he_6ghz_capa.capa = cpu_to_le16(cap);
}
idx++;
}
@ -221,7 +233,7 @@ int __mt7921_start(struct mt7921_phy *phy)
if (err)
return err;
err = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
err = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
if (err)
return err;
@ -318,12 +330,6 @@ static int mt7921_add_interface(struct ieee80211_hw *hw,
mtxq->wcid = &mvif->sta.wcid;
}
if (vif->type != NL80211_IFTYPE_AP &&
(!mvif->mt76.omac_idx || mvif->mt76.omac_idx > 3))
vif->offload_flags = 0;
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
out:
mt7921_mutex_release(dev);
@ -369,7 +375,7 @@ static int mt7921_set_channel(struct mt7921_phy *phy)
mt76_set_channel(phy->mt76);
ret = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD_CHANNEL_SWITCH);
ret = mt7921_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));
if (ret)
goto out;
@ -462,7 +468,7 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed)
{
struct mt7921_dev *dev = mt7921_hw_dev(hw);
struct mt7921_phy *phy = mt7921_hw_phy(hw);
int ret;
int ret = 0;
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
ieee80211_stop_queues(hw);
@ -474,8 +480,11 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed)
mt7921_mutex_acquire(dev);
if (changed & IEEE80211_CONF_CHANGE_POWER)
mt76_connac_mcu_set_rate_txpower(phy->mt76);
if (changed & IEEE80211_CONF_CHANGE_POWER) {
ret = mt76_connac_mcu_set_rate_txpower(phy->mt76);
if (ret)
goto out;
}
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
bool enabled = !!(hw->conf.flags & IEEE80211_CONF_MONITOR);
@ -490,9 +499,10 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed)
mt76_wr(dev, MT_WF_RFCR(0), phy->rxfilter);
}
out:
mt7921_mutex_release(dev);
return 0;
return ret;
}
static int
@ -1238,7 +1248,6 @@ static int mt7921_suspend(struct ieee80211_hw *hw,
{
struct mt7921_dev *dev = mt7921_hw_dev(hw);
struct mt7921_phy *phy = mt7921_hw_phy(hw);
int err;
cancel_delayed_work_sync(&phy->scan_work);
cancel_delayed_work_sync(&phy->mt76->mac_work);
@ -1249,34 +1258,24 @@ static int mt7921_suspend(struct ieee80211_hw *hw,
mt7921_mutex_acquire(dev);
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
set_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
ieee80211_iterate_active_interfaces(hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76_connac_mcu_set_suspend_iter,
&dev->mphy);
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
mt7921_mutex_release(dev);
return err;
return 0;
}
static int mt7921_resume(struct ieee80211_hw *hw)
{
struct mt7921_dev *dev = mt7921_hw_dev(hw);
struct mt7921_phy *phy = mt7921_hw_phy(hw);
int err;
mt7921_mutex_acquire(dev);
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
if (err < 0)
goto out;
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
clear_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
ieee80211_iterate_active_interfaces(hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76_connac_mcu_set_suspend_iter,
@ -1284,11 +1283,10 @@ static int mt7921_resume(struct ieee80211_hw *hw)
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
MT7921_WATCHDOG_TIME);
out:
mt7921_mutex_release(dev);
return err;
return 0;
}
static void mt7921_set_wakeup(struct ieee80211_hw *hw, bool enabled)
@ -1334,41 +1332,23 @@ static void mt7921_sta_set_decap_offload(struct ieee80211_hw *hw,
clear_bit(MT_WCID_FLAG_HDR_TRANS, &msta->wcid.flags);
mt76_connac_mcu_sta_update_hdr_trans(&dev->mt76, vif, &msta->wcid,
MCU_UNI_CMD_STA_REC_UPDATE);
MCU_UNI_CMD(STA_REC_UPDATE));
}
static int mt7921_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
const struct cfg80211_sar_capa *capa = hw->wiphy->sar_capa;
struct mt7921_dev *dev = mt7921_hw_dev(hw);
struct mt76_freq_range_power *data, *frp;
struct mt76_phy *mphy = hw->priv;
int err;
u32 i;
if (sar->type != NL80211_SAR_TYPE_POWER || !sar->num_sub_specs)
return -EINVAL;
mt7921_mutex_acquire(dev);
data = mphy->frp;
for (i = 0; i < sar->num_sub_specs; i++) {
u32 index = sar->sub_specs[i].freq_range_index;
/* SAR specifies power limitaton in 0.25dbm */
s32 power = sar->sub_specs[i].power >> 1;
if (power > 127 || power < -127)
power = 127;
frp = &data[index];
frp->range = &capa->freq_ranges[index];
frp->power = power;
}
err = mt76_init_sar_power(hw, sar);
if (err)
goto out;
err = mt76_connac_mcu_set_rate_txpower(mphy);
out:
mt7921_mutex_release(dev);
return err;

View file

@ -93,9 +93,6 @@ struct mt7921_fw_region {
#define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK GENMASK(15, 0)
#define PATCH_SEC_ENC_AES_KEY_MASK GENMASK(7, 0)
#define to_wcid_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id)
#define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id)
static enum mcu_cipher_type
mt7921_mcu_get_cipher(int cipher)
{
@ -163,8 +160,8 @@ mt7921_mcu_parse_eeprom(struct mt76_dev *dev, struct sk_buff *skb)
int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
struct sk_buff *skb, int seq)
{
int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
struct mt7921_mcu_rxd *rxd;
int mcu_cmd = cmd & MCU_CMD_MASK;
int ret = 0;
if (!skb) {
@ -179,24 +176,20 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
if (seq != rxd->seq)
return -EAGAIN;
switch (cmd) {
case MCU_CMD_PATCH_SEM_CONTROL:
if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
skb_pull(skb, sizeof(*rxd) - 4);
ret = *skb->data;
break;
case MCU_EXT_CMD_GET_TEMP:
} else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
skb_pull(skb, sizeof(*rxd) + 4);
ret = le32_to_cpu(*(__le32 *)skb->data);
break;
case MCU_EXT_CMD_EFUSE_ACCESS:
} else if (cmd == MCU_EXT_CMD(EFUSE_ACCESS)) {
ret = mt7921_mcu_parse_eeprom(mdev, skb);
break;
case MCU_UNI_CMD_DEV_INFO_UPDATE:
case MCU_UNI_CMD_BSS_INFO_UPDATE:
case MCU_UNI_CMD_STA_REC_UPDATE:
case MCU_UNI_CMD_HIF_CTRL:
case MCU_UNI_CMD_OFFLOAD:
case MCU_UNI_CMD_SUSPEND: {
} else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
cmd == MCU_UNI_CMD(HIF_CTRL) ||
cmd == MCU_UNI_CMD(OFFLOAD) ||
cmd == MCU_UNI_CMD(SUSPEND)) {
struct mt7921_mcu_uni_event *event;
skb_pull(skb, sizeof(*rxd));
@ -205,19 +198,14 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
/* skip invalid event */
if (mcu_cmd != event->cid)
ret = -EAGAIN;
break;
}
case MCU_CMD_REG_READ: {
} else if (cmd == MCU_CE_QUERY(REG_READ)) {
struct mt7921_mcu_reg_event *event;
skb_pull(skb, sizeof(*rxd));
event = (struct mt7921_mcu_reg_event *)skb->data;
ret = (int)le32_to_cpu(event->val);
break;
}
default:
} else {
skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
break;
}
return ret;
@ -228,32 +216,28 @@ int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
int cmd, int *wait_seq)
{
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
int txd_len, mcu_cmd = cmd & MCU_CMD_MASK;
int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
struct mt7921_uni_txd *uni_txd;
struct mt7921_mcu_txd *mcu_txd;
__le32 *txd;
u32 val;
u8 seq;
switch (cmd) {
case MCU_UNI_CMD_HIF_CTRL:
case MCU_UNI_CMD_SUSPEND:
case MCU_UNI_CMD_OFFLOAD:
mdev->mcu.timeout = HZ / 3;
break;
default:
if (cmd == MCU_UNI_CMD(HIF_CTRL) ||
cmd == MCU_UNI_CMD(SUSPEND) ||
cmd == MCU_UNI_CMD(OFFLOAD))
mdev->mcu.timeout = HZ;
else
mdev->mcu.timeout = 3 * HZ;
break;
}
seq = ++dev->mt76.mcu.msg_seq & 0xf;
if (!seq)
seq = ++dev->mt76.mcu.msg_seq & 0xf;
if (cmd == MCU_CMD_FW_SCATTER)
if (cmd == MCU_CMD(FW_SCATTER))
goto exit;
txd_len = cmd & MCU_UNI_PREFIX ? sizeof(*uni_txd) : sizeof(*mcu_txd);
txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);
txd = (__le32 *)skb_push(skb, txd_len);
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
@ -265,7 +249,7 @@ int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);
txd[1] = cpu_to_le32(val);
if (cmd & MCU_UNI_PREFIX) {
if (cmd & __MCU_CMD_FIELD_UNI) {
uni_txd = (struct mt7921_uni_txd *)txd;
uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));
uni_txd->option = MCU_CMD_UNI_EXT_ACK;
@ -283,33 +267,19 @@ int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
MT_TX_MCU_PORT_RX_Q0));
mcu_txd->pkt_type = MCU_PKT_ID;
mcu_txd->seq = seq;
switch (cmd & ~MCU_CMD_MASK) {
case MCU_FW_PREFIX:
mcu_txd->set_query = MCU_Q_NA;
mcu_txd->cid = mcu_cmd;
break;
case MCU_CE_PREFIX:
if (cmd & MCU_QUERY_MASK)
mcu_txd->set_query = MCU_Q_QUERY;
else
mcu_txd->set_query = MCU_Q_SET;
mcu_txd->cid = mcu_cmd;
break;
default:
mcu_txd->cid = MCU_CMD_EXT_CID;
if (cmd & MCU_QUERY_PREFIX || cmd == MCU_EXT_CMD_EFUSE_ACCESS)
mcu_txd->set_query = MCU_Q_QUERY;
else
mcu_txd->set_query = MCU_Q_SET;
mcu_txd->ext_cid = mcu_cmd;
mcu_txd->ext_cid_ack = 1;
break;
}
mcu_txd->cid = mcu_cmd;
mcu_txd->s2d_index = MCU_S2D_H2N;
WARN_ON(cmd == MCU_EXT_CMD_EFUSE_ACCESS &&
mcu_txd->set_query != MCU_Q_QUERY);
mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) {
if (cmd & __MCU_CMD_FIELD_QUERY)
mcu_txd->set_query = MCU_Q_QUERY;
else
mcu_txd->set_query = MCU_Q_SET;
mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid;
} else {
mcu_txd->set_query = MCU_Q_NA;
}
exit:
if (wait_seq)
@ -418,6 +388,17 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
trace_lp_event(dev, event->state);
}
static void
mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
{
struct mt7921_mcu_tx_done_event *event;
skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
event = (struct mt7921_mcu_tx_done_event *)skb->data;
mt7921_mac_add_txs(dev, event->txs);
}
static void
mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
{
@ -445,6 +426,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
case MCU_EVENT_LP_INFO:
mt7921_mcu_low_power_event(dev, skb);
break;
case MCU_EVENT_TX_DONE:
mt7921_mcu_tx_done_event(dev, skb);
break;
default:
break;
}
@ -567,7 +551,7 @@ int mt7921_mcu_add_key(struct mt7921_dev *dev, struct ieee80211_vif *vif,
return ret;
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_UNI_CMD_STA_REC_UPDATE, true);
MCU_UNI_CMD(STA_REC_UPDATE), true);
}
int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev,
@ -602,7 +586,7 @@ int mt7921_mcu_restart(struct mt76_dev *dev)
.power_mode = 1,
};
return mt76_mcu_send_msg(dev, MCU_CMD_NIC_POWER_CTRL, &req,
return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req,
sizeof(req), false);
}
EXPORT_SYMBOL_GPL(mt7921_mcu_restart);
@ -708,7 +692,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
goto out;
}
ret = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD_FW_SCATTER,
ret = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
dl, len, max_len);
if (ret) {
dev_err(dev->mt76.dev, "Failed to send patch\n");
@ -720,6 +704,17 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
if (ret)
dev_err(dev->mt76.dev, "Failed to start patch\n");
if (mt76_is_sdio(&dev->mt76)) {
/* activate again */
ret = __mt7921_mcu_fw_pmctrl(dev);
if (ret)
return ret;
ret = __mt7921_mcu_drv_pmctrl(dev);
if (ret)
return ret;
}
out:
sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false);
switch (sem) {
@ -782,7 +777,7 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev,
return err;
}
err = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD_FW_SCATTER,
err = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
data + offset, len, max_len);
if (err) {
dev_err(dev->mt76.dev, "Failed to send firmware.\n");
@ -882,7 +877,7 @@ static int mt7921_load_firmware(struct mt7921_dev *dev)
dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
#endif /* CONFIG_PM */
dev_err(dev->mt76.dev, "Firmware init done\n");
dev_dbg(dev->mt76.dev, "Firmware init done\n");
return 0;
}
@ -896,8 +891,8 @@ int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl)
.ctrl_val = ctrl
};
return mt76_mcu_send_msg(&dev->mt76, MCU_CMD_FWLOG_2_HOST, &data,
sizeof(data), false);
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(FWLOG_2_HOST),
&data, sizeof(data), false);
}
int mt7921_run_firmware(struct mt7921_dev *dev)
@ -997,8 +992,8 @@ int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif)
e->cw_max = cpu_to_le16(10);
}
ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EDCA_UPDATE, &req,
sizeof(req), true);
ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EDCA_UPDATE),
&req, sizeof(req), true);
if (ret)
return ret;
@ -1022,8 +1017,8 @@ int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif)
e->timer = q->mu_edca_timer;
}
return mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_MU_EDCA_PARMS, &req_mu,
sizeof(req_mu), false);
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_MU_EDCA_PARMS),
&req_mu, sizeof(req_mu), false);
}
int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
@ -1070,7 +1065,7 @@ int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
else
req.switch_reason = CH_SWITCH_NORMAL;
if (cmd == MCU_EXT_CMD_CHANNEL_SWITCH)
if (cmd == MCU_EXT_CMD(CHANNEL_SWITCH))
req.rx_streams = hweight8(req.rx_streams);
if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
@ -1093,7 +1088,7 @@ int mt7921_mcu_set_eeprom(struct mt7921_dev *dev)
.format = EE_FORMAT_WHOLE,
};
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_BUFFER_MODE,
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_BUFFER_MODE),
&req, sizeof(req), true);
}
EXPORT_SYMBOL_GPL(mt7921_mcu_set_eeprom);
@ -1108,8 +1103,9 @@ int mt7921_mcu_get_eeprom(struct mt7921_dev *dev, u32 offset)
int ret;
u8 *buf;
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_ACCESS, &req,
sizeof(req), true, &skb);
ret = mt76_mcu_send_and_get_msg(&dev->mt76,
MCU_EXT_QUERY(EFUSE_ACCESS),
&req, sizeof(req), true, &skb);
if (ret)
return ret;
@ -1154,7 +1150,7 @@ int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif)
if (vif->type != NL80211_IFTYPE_STATION)
return -EOPNOTSUPP;
return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_BSS_INFO_UPDATE,
return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
&ps_req, sizeof(ps_req), true);
}
@ -1190,7 +1186,7 @@ mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif,
if (vif->type != NL80211_IFTYPE_STATION)
return 0;
return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_BSS_INFO_UPDATE,
return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
&bcnft_req, sizeof(bcnft_req), true);
}
@ -1226,13 +1222,13 @@ mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
if (vif->type != NL80211_IFTYPE_STATION)
return 0;
err = mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_BSS_ABORT, &req_hdr,
sizeof(req_hdr), false);
err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),
&req_hdr, sizeof(req_hdr), false);
if (err < 0 || !enable)
return err;
return mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_BSS_CONNECTED, &req,
sizeof(req), false);
return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_CONNECTED),
&req, sizeof(req), false);
}
int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta,
@ -1245,7 +1241,7 @@ int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta,
.sta = sta,
.vif = vif,
.enable = enable,
.cmd = MCU_UNI_CMD_STA_REC_UPDATE,
.cmd = MCU_UNI_CMD(STA_REC_UPDATE),
.state = state,
.offload_fw = true,
.rcpi = to_rcpi(rssi),
@ -1342,7 +1338,7 @@ int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr)
struct sk_buff *skb;
int ret;
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CMD_GET_TXPWR,
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CE_CMD(GET_TXPWR),
&req, sizeof(req), true, &skb);
if (ret)
return ret;

View file

@ -76,20 +76,32 @@ struct mt7921_uni_txd {
u8 reserved2[4];
} __packed __aligned(4);
/* event table */
enum {
MCU_EVENT_REG_ACCESS = 0x05,
MCU_EVENT_LP_INFO = 0x07,
MCU_EVENT_SCAN_DONE = 0x0d,
MCU_EVENT_TX_DONE = 0x0f,
MCU_EVENT_BSS_ABSENCE = 0x11,
MCU_EVENT_BSS_BEACON_LOSS = 0x13,
MCU_EVENT_CH_PRIVILEGE = 0x18,
MCU_EVENT_SCHED_SCAN_DONE = 0x23,
MCU_EVENT_DBG_MSG = 0x27,
MCU_EVENT_TXPWR = 0xd0,
MCU_EVENT_COREDUMP = 0xf0,
};
struct mt7921_mcu_tx_done_event {
u8 pid;
u8 status;
__le16 seq;
u8 wlan_idx;
u8 tx_cnt;
__le16 tx_rate;
u8 flag;
u8 tid;
u8 rsp_rate;
u8 mcs;
u8 bw;
u8 tx_pwr;
u8 reason;
u8 rsv0[1];
__le32 delay;
__le32 timestamp;
__le32 applied_flag;
u8 txs[28];
u8 rsv1[32];
} __packed;
/* ext event table */
enum {
@ -126,130 +138,17 @@ struct mt7921_mcu_eeprom_info {
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
#define MCU_PKT_ID 0xa0
enum {
MCU_Q_QUERY,
MCU_Q_SET,
MCU_Q_RESERVED,
MCU_Q_NA
};
enum {
MCU_S2D_H2N,
MCU_S2D_C2N,
MCU_S2D_H2C,
MCU_S2D_H2CN
};
struct mt7921_mcu_uni_event {
u8 cid;
u8 pad[3];
__le32 status; /* 0: success, others: fail */
} __packed;
enum {
PATCH_NOT_DL_SEM_FAIL,
PATCH_IS_DL,
PATCH_NOT_DL_SEM_SUCCESS,
PATCH_REL_SEM_SUCCESS
};
enum {
FW_STATE_INITIAL,
FW_STATE_FW_DOWNLOAD,
FW_STATE_NORMAL_OPERATION,
FW_STATE_NORMAL_TRX,
FW_STATE_WACPU_RDY = 7
};
enum {
EE_MODE_EFUSE,
EE_MODE_BUFFER,
};
enum {
EE_FORMAT_BIN,
EE_FORMAT_WHOLE,
EE_FORMAT_MULTIPLE,
};
enum {
MCU_PHY_STATE_TX_RATE,
MCU_PHY_STATE_RX_RATE,
MCU_PHY_STATE_RSSI,
MCU_PHY_STATE_CONTENTION_RX_RATE,
MCU_PHY_STATE_OFDMLQ_CNINFO,
};
struct sec_key {
u8 cipher_id;
u8 cipher_len;
u8 key_id;
u8 key_len;
u8 key[32];
} __packed;
struct sta_rec_sec {
__le16 tag;
__le16 len;
u8 add;
u8 n_cipher;
u8 rsv[2];
struct sec_key key[2];
} __packed;
enum mcu_cipher_type {
MCU_CIPHER_NONE = 0,
MCU_CIPHER_WEP40,
MCU_CIPHER_WEP104,
MCU_CIPHER_WEP128,
MCU_CIPHER_TKIP,
MCU_CIPHER_AES_CCMP,
MCU_CIPHER_CCMP_256,
MCU_CIPHER_GCMP,
MCU_CIPHER_GCMP_256,
MCU_CIPHER_WAPI,
MCU_CIPHER_BIP_CMAC_128,
};
enum {
CH_SWITCH_NORMAL = 0,
CH_SWITCH_SCAN = 3,
CH_SWITCH_MCC = 4,
CH_SWITCH_DFS = 5,
CH_SWITCH_BACKGROUND_SCAN_START = 6,
CH_SWITCH_BACKGROUND_SCAN_RUNNING = 7,
CH_SWITCH_BACKGROUND_SCAN_STOP = 8,
CH_SWITCH_SCAN_BYPASS_DPD = 9
};
enum {
THERMAL_SENSOR_TEMP_QUERY,
THERMAL_SENSOR_MANUAL_CTRL,
THERMAL_SENSOR_INFO_QUERY,
THERMAL_SENSOR_TASK_CTRL,
};
enum {
MT_EBF = BIT(0), /* explicit beamforming */
MT_IBF = BIT(1) /* implicit beamforming */
};
#define STA_CAP_WMM BIT(0)
#define STA_CAP_SGI_20 BIT(4)
#define STA_CAP_SGI_40 BIT(5)
#define STA_CAP_TX_STBC BIT(6)
#define STA_CAP_RX_STBC BIT(7)
#define STA_CAP_VHT_SGI_80 BIT(16)
#define STA_CAP_VHT_SGI_160 BIT(17)
#define STA_CAP_VHT_TX_STBC BIT(18)
#define STA_CAP_VHT_RX_STBC BIT(19)
#define STA_CAP_VHT_LDPC BIT(23)
#define STA_CAP_LDPC BIT(24)
#define STA_CAP_HT BIT(26)
#define STA_CAP_VHT BIT(27)
#define STA_CAP_HE BIT(28)
struct mt7921_mcu_reg_event {
__le32 reg;
__le32 val;

View file

@ -446,6 +446,7 @@ int mt7921_mcu_restart(struct mt76_dev *dev);
void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb);
int mt7921e_driver_own(struct mt7921_dev *dev);
int mt7921e_mac_reset(struct mt7921_dev *dev);
int mt7921e_mcu_init(struct mt7921_dev *dev);
int mt7921s_wfsys_reset(struct mt7921_dev *dev);
@ -463,4 +464,5 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct mt76_tx_info *tx_info);
void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data);
#endif

View file

@ -15,6 +15,8 @@
static const struct pci_device_id mt7921_pci_device_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961) },
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922) },
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0608) },
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x0616) },
{ },
};
@ -188,7 +190,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev,
tasklet_init(&dev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev);
mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) |
(mt7921_l1_rr(dev, MT_HW_REV) & 0xff);
dev_err(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
@ -235,7 +237,6 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
struct mt76_dev *mdev = pci_get_drvdata(pdev);
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
struct mt76_connac_pm *pm = &dev->pm;
bool hif_suspend;
int i, err;
pm->suspended = true;
@ -246,12 +247,9 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
if (err < 0)
goto restore_suspend;
hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
if (hif_suspend) {
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
if (err)
goto restore_suspend;
}
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
if (err)
goto restore_suspend;
/* always enable deep sleep during suspend to reduce
* power consumption
@ -302,8 +300,7 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
if (!pm->ds_enable)
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
if (hif_suspend)
mt76_connac_mcu_set_hif_suspend(mdev, false);
mt76_connac_mcu_set_hif_suspend(mdev, false);
restore_suspend:
pm->suspended = false;
@ -318,7 +315,6 @@ static int mt7921_pci_resume(struct pci_dev *pdev)
struct mt76_connac_pm *pm = &dev->pm;
int i, err;
pm->suspended = false;
err = pci_set_power_state(pdev, PCI_D0);
if (err)
return err;
@ -356,8 +352,11 @@ static int mt7921_pci_resume(struct pci_dev *pdev)
if (!pm->ds_enable)
mt76_connac_mcu_set_deep_sleep(&dev->mt76, false);
if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state))
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
if (err)
return err;
pm->suspended = false;
return err;
}

View file

@ -321,6 +321,10 @@ int mt7921e_mac_reset(struct mt7921_dev *dev)
MT_INT_MCU_CMD);
mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
err = mt7921e_driver_own(dev);
if (err)
return err;
err = mt7921_run_firmware(dev);
if (err)
goto out;

View file

@ -4,7 +4,7 @@
#include "mt7921.h"
#include "mcu.h"
static int mt7921e_driver_own(struct mt7921_dev *dev)
int mt7921e_driver_own(struct mt7921_dev *dev)
{
u32 reg = mt7921_reg_map_l1(dev, MT_TOP_LPCR_HOST_BAND0);
@ -30,7 +30,7 @@ mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
if (ret)
return ret;
if (cmd == MCU_CMD_FW_SCATTER)
if (cmd == MCU_CMD(FW_SCATTER))
txq = MT_MCUQ_FWDL;
return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);

View file

@ -62,6 +62,10 @@ static int mt7921s_parse_intr(struct mt76_dev *dev, struct mt76s_intr *intr)
if (err < 0)
return err;
if (irq_data->rx.num[0] > 16 ||
irq_data->rx.num[1] > 128)
return -EINVAL;
intr->isr = irq_data->isr;
intr->rec_mb = irq_data->rec_mb;
intr->tx.wtqcr = irq_data->tx.wtqcr;
@ -203,10 +207,11 @@ static int mt7921s_suspend(struct device *__dev)
struct mt7921_dev *dev = sdio_get_drvdata(func);
struct mt76_connac_pm *pm = &dev->pm;
struct mt76_dev *mdev = &dev->mt76;
bool hif_suspend;
int err;
pm->suspended = true;
set_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
cancel_delayed_work_sync(&pm->ps_work);
cancel_work_sync(&pm->wake_work);
@ -214,13 +219,6 @@ static int mt7921s_suspend(struct device *__dev)
if (err < 0)
goto restore_suspend;
hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
if (hif_suspend) {
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
if (err)
goto restore_suspend;
}
/* always enable deep sleep during suspend to reduce
* power consumption
*/
@ -228,35 +226,45 @@ static int mt7921s_suspend(struct device *__dev)
mt76_txq_schedule_all(&dev->mphy);
mt76_worker_disable(&mdev->tx_worker);
mt76_worker_disable(&mdev->sdio.txrx_worker);
mt76_worker_disable(&mdev->sdio.status_worker);
mt76_worker_disable(&mdev->sdio.net_worker);
cancel_work_sync(&mdev->sdio.stat_work);
clear_bit(MT76_READING_STATS, &dev->mphy.state);
mt76_tx_status_check(mdev, true);
mt76_worker_schedule(&mdev->sdio.txrx_worker);
wait_event_timeout(dev->mt76.sdio.wait,
mt76s_txqs_empty(&dev->mt76), 5 * HZ);
/* It is supposed that SDIO bus is idle at the point */
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
if (err)
goto restore_worker;
mt76_worker_disable(&mdev->sdio.txrx_worker);
mt76_worker_disable(&mdev->sdio.net_worker);
err = mt7921_mcu_fw_pmctrl(dev);
if (err)
goto restore_worker;
goto restore_txrx_worker;
sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
return 0;
restore_txrx_worker:
mt76_worker_enable(&mdev->sdio.net_worker);
mt76_worker_enable(&mdev->sdio.txrx_worker);
mt76_connac_mcu_set_hif_suspend(mdev, false);
restore_worker:
mt76_worker_enable(&mdev->tx_worker);
mt76_worker_enable(&mdev->sdio.txrx_worker);
mt76_worker_enable(&mdev->sdio.status_worker);
mt76_worker_enable(&mdev->sdio.net_worker);
if (!pm->ds_enable)
mt76_connac_mcu_set_deep_sleep(mdev, false);
if (hif_suspend)
mt76_connac_mcu_set_hif_suspend(mdev, false);
restore_suspend:
clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
pm->suspended = false;
return err;
@ -270,7 +278,7 @@ static int mt7921s_resume(struct device *__dev)
struct mt76_dev *mdev = &dev->mt76;
int err;
pm->suspended = false;
clear_bit(MT76_STATE_SUSPEND, &mdev->phy.state);
err = mt7921_mcu_drv_pmctrl(dev);
if (err < 0)
@ -285,8 +293,11 @@ static int mt7921s_resume(struct device *__dev)
if (!pm->ds_enable)
mt76_connac_mcu_set_deep_sleep(mdev, false);
if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state))
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
if (err)
return err;
pm->suspended = false;
return err;
}

View file

@ -219,5 +219,5 @@ bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update)
mt7921_mac_sta_poll(dev);
mt7921_mutex_release(dev);
return 0;
return false;
}

View file

@ -33,7 +33,7 @@ mt7921s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
if (ret)
return ret;
if (cmd == MCU_CMD_FW_SCATTER)
if (cmd == MCU_CMD(FW_SCATTER))
type = MT7921_SDIO_FWDL;
mt7921_skb_add_sdio_hdr(skb, type);

View file

@ -66,7 +66,7 @@ mt7921_tm_set(struct mt7921_dev *dev, struct mt7921_tm_cmd *req)
if (!mt76_testmode_enabled(phy))
goto out;
ret = mt76_mcu_send_msg(&dev->mt76, MCU_CMD_TEST_CTRL, &cmd,
ret = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(TEST_CTRL), &cmd,
sizeof(cmd), false);
if (ret)
goto out;
@ -95,7 +95,7 @@ mt7921_tm_query(struct mt7921_dev *dev, struct mt7921_tm_cmd *req,
struct sk_buff *skb;
int ret;
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CMD_TEST_CTRL,
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CE_CMD(TEST_CTRL),
&cmd, sizeof(cmd), true, &skb);
if (ret)
goto out;

View file

@ -305,12 +305,12 @@ int mt76s_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid)
spin_lock_init(&q->lock);
q->entry = devm_kcalloc(dev->dev,
MT_NUM_RX_ENTRIES, sizeof(*q->entry),
MT76S_NUM_RX_ENTRIES, sizeof(*q->entry),
GFP_KERNEL);
if (!q->entry)
return -ENOMEM;
q->ndesc = MT_NUM_RX_ENTRIES;
q->ndesc = MT76S_NUM_RX_ENTRIES;
q->head = q->tail = 0;
q->queued = 0;
@ -328,12 +328,12 @@ static struct mt76_queue *mt76s_alloc_tx_queue(struct mt76_dev *dev)
spin_lock_init(&q->lock);
q->entry = devm_kcalloc(dev->dev,
MT_NUM_TX_ENTRIES, sizeof(*q->entry),
MT76S_NUM_TX_ENTRIES, sizeof(*q->entry),
GFP_KERNEL);
if (!q->entry)
return ERR_PTR(-ENOMEM);
q->ndesc = MT_NUM_TX_ENTRIES;
q->ndesc = MT76S_NUM_TX_ENTRIES;
return q;
}
@ -479,7 +479,8 @@ static void mt76s_status_worker(struct mt76_worker *w)
resched = true;
if (dev->drv->tx_status_data &&
!test_and_set_bit(MT76_READING_STATS, &dev->phy.state))
!test_and_set_bit(MT76_READING_STATS, &dev->phy.state) &&
!test_bit(MT76_STATE_SUSPEND, &dev->phy.state))
queue_work(dev->wq, &dev->sdio.stat_work);
} while (nframes > 0);

View file

@ -317,7 +317,8 @@ void mt76s_txrx_worker(struct mt76_sdio *sdio)
if (ret > 0)
nframes += ret;
if (test_bit(MT76_MCU_RESET, &dev->phy.state)) {
if (test_bit(MT76_MCU_RESET, &dev->phy.state) ||
test_bit(MT76_STATE_SUSPEND, &dev->phy.state)) {
if (!mt76s_txqs_empty(dev))
continue;
else

View file

@ -126,9 +126,9 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
hdr = __skb_put_zero(head, head_len);
hdr->frame_control = cpu_to_le16(fc);
memcpy(hdr->addr1, phy->macaddr, sizeof(phy->macaddr));
memcpy(hdr->addr2, phy->macaddr, sizeof(phy->macaddr));
memcpy(hdr->addr3, phy->macaddr, sizeof(phy->macaddr));
memcpy(hdr->addr1, td->addr[0], ETH_ALEN);
memcpy(hdr->addr2, td->addr[1], ETH_ALEN);
memcpy(hdr->addr3, td->addr[2], ETH_ALEN);
skb_set_queue_mapping(head, IEEE80211_AC_BE);
info = IEEE80211_SKB_CB(head);
@ -318,6 +318,10 @@ mt76_testmode_init_defaults(struct mt76_phy *phy)
td->tx_count = 1;
td->tx_rate_mode = MT76_TM_TX_MODE_OFDM;
td->tx_rate_nss = 1;
memcpy(td->addr[0], phy->macaddr, ETH_ALEN);
memcpy(td->addr[1], phy->macaddr, ETH_ALEN);
memcpy(td->addr[2], phy->macaddr, ETH_ALEN);
}
static int
@ -493,6 +497,20 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
}
if (tb[MT76_TM_ATTR_MAC_ADDRS]) {
struct nlattr *cur;
int idx = 0;
int rem;
nla_for_each_nested(cur, tb[MT76_TM_ATTR_MAC_ADDRS], rem) {
if (nla_len(cur) != ETH_ALEN || idx >= 3)
goto out;
memcpy(td->addr[idx], nla_data(cur), ETH_ALEN);
idx++;
}
}
if (dev->test_ops->set_params) {
err = dev->test_ops->set_params(phy, tb, state);
if (err)
@ -635,6 +653,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
nla_nest_end(msg, a);
}
if (mt76_testmode_param_present(td, MT76_TM_ATTR_MAC_ADDRS)) {
a = nla_nest_start(msg, MT76_TM_ATTR_MAC_ADDRS);
if (!a)
goto out;
for (i = 0; i < 3; i++)
if (nla_put(msg, i, ETH_ALEN, td->addr[i]))
goto out;
nla_nest_end(msg, a);
}
err = 0;
out:

View file

@ -45,6 +45,8 @@
* @MT76_TM_ATTR_TX_TIME: packet transmission time, in unit of us (u32)
*
* @MT76_TM_ATTR_DRV_DATA: driver specific netlink attrs (nested)
*
* @MT76_TM_ATTR_MAC_ADDRS: array of nested MAC addresses (nested)
*/
enum mt76_testmode_attr {
MT76_TM_ATTR_UNSPEC,
@ -81,6 +83,8 @@ enum mt76_testmode_attr {
MT76_TM_ATTR_DRV_DATA,
MT76_TM_ATTR_MAC_ADDRS,
/* keep last */
NUM_MT76_TM_ATTRS,
MT76_TM_ATTR_MAX = NUM_MT76_TM_ATTRS - 1,