Commit d8f9bb98 authored by Kalle Valo's avatar Kalle Valo

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
parents f85b244e b1460bb4
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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");
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 |
......
......@@ -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);
}
}
......
......@@ -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)
......
......@@ -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;
......
......@@ -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
......@@ -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;
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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;
......
......@@ -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,
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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)
......
......@@ -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)
......
......@@ -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);
......
......@@ -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);
......
......@@ -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)
{
......
......@@ -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);
......
......@@ -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)
......
......@@ -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,
};
......@@ -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)
......
......@@ -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,
};
......@@ -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,
......
// 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,6 +25,49 @@ 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_check_eeprom(struct mt7915_dev *dev)
{
u8 *eeprom = dev->mt76.eeprom.data;
u16 val = get_unaligned_le16(eeprom);
switch (val) {
case 0x7915:
return 0;
default:
return -EINVAL;
}
}
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;
......@@ -31,10 +78,16 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
if (ret) {
dev->flash_mode = true;
ret = mt7915_eeprom_load_precal(dev);
} 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++)
......@@ -42,20 +95,7 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
i * MT7915_EEPROM_BLOCK_SIZE);
}
return ret;
}
static int mt7915_check_eeprom(struct mt7915_dev *dev)
{
u8 *eeprom = dev->mt76.eeprom.data;
u16 val = get_unaligned_le16(eeprom);
switch (val) {
case 0x7915:
return 0;
default:
return -EINVAL;
}
return mt7915_check_eeprom(dev);
}
void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
......@@ -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;
dev_warn(dev->mt76.dev, "eeprom load fail, use default bin\n");
ret = mt7915_eeprom_load_default(dev);
if (ret)
return ret;
}
ret = mt7915_check_eeprom(dev);
ret = mt7915_eeprom_load_precal(dev);
if (ret)
return ret;
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -361,16 +361,15 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
return;
}
if (b)
return;
b = devm_kzalloc(dev->mt76.dev, 4 * n_regs, GFP_KERNEL);
if (!b)
return;
if (!b) {
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 |
......
......@@ -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
......@@ -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;
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment