Commit b865273b authored by Kalle Valo's avatar Kalle Valo

Merge tag 'mt76-for-kvalo-2022-02-24' of https://github.com/nbd168/wireless

mt76 patches for 5.18

- bugfixes
- mt7915 thermal management improvements
- SAR support for more mt76 drivers
- mt7986 wmac support on mt7915
parents a0061be4 00a883e6
...@@ -18,7 +18,7 @@ description: | ...@@ -18,7 +18,7 @@ description: |
wireless device. The node is expected to be specified as a child wireless device. The node is expected to be specified as a child
node of the PCI controller to which the wireless chip is connected. node of the PCI controller to which the wireless chip is connected.
Alternatively, it can specify the wireless part of the MT7628/MT7688 Alternatively, it can specify the wireless part of the MT7628/MT7688
or MT7622 SoC. or MT7622/MT7986 SoC.
allOf: allOf:
- $ref: ieee80211.yaml# - $ref: ieee80211.yaml#
...@@ -29,9 +29,13 @@ properties: ...@@ -29,9 +29,13 @@ properties:
- mediatek,mt76 - mediatek,mt76
- mediatek,mt7628-wmac - mediatek,mt7628-wmac
- mediatek,mt7622-wmac - mediatek,mt7622-wmac
- mediatek,mt7986-wmac
reg: reg:
maxItems: 1 minItems: 1
maxItems: 3
description:
MT7986 should contain 3 regions consys, dcm, and sku, in this order.
interrupts: interrupts:
maxItems: 1 maxItems: 1
...@@ -39,6 +43,17 @@ properties: ...@@ -39,6 +43,17 @@ properties:
power-domains: power-domains:
maxItems: 1 maxItems: 1
memory-region:
maxItems: 1
resets:
maxItems: 1
description:
Specify the consys reset for mt7986.
reset-name:
const: consys
mediatek,infracfg: mediatek,infracfg:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
description: description:
...@@ -174,7 +189,7 @@ required: ...@@ -174,7 +189,7 @@ required:
- compatible - compatible
- reg - reg
additionalProperties: false unevaluatedProperties: false
examples: examples:
- | - |
...@@ -240,3 +255,15 @@ examples: ...@@ -240,3 +255,15 @@ examples:
power-domains = <&scpsys 3>; power-domains = <&scpsys 3>;
}; };
- |
wifi@18000000 {
compatible = "mediatek,mt7986-wmac";
resets = <&watchdog 23>;
reset-names = "consys";
reg = <0x18000000 0x1000000>,
<0x10003000 0x1000>,
<0x11d10000 0x1000>;
interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
memory-region = <&wmcpu_emi>;
};
...@@ -932,6 +932,35 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, ...@@ -932,6 +932,35 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
} }
EXPORT_SYMBOL(mt76_wcid_key_setup); EXPORT_SYMBOL(mt76_wcid_key_setup);
static int
mt76_rx_signal(struct mt76_rx_status *status)
{
s8 *chain_signal = status->chain_signal;
int signal = -128;
u8 chains;
for (chains = status->chains; chains; chains >>= 1, chain_signal++) {
int cur, diff;
if (!(chains & BIT(0)))
continue;
cur = *chain_signal;
if (cur > signal)
swap(cur, signal);
diff = signal - cur;
if (diff == 0)
signal += 3;
else if (diff <= 2)
signal += 2;
else if (diff <= 6)
signal += 1;
}
return signal;
}
static void static void
mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
struct ieee80211_hw **hw, struct ieee80211_hw **hw,
...@@ -960,6 +989,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, ...@@ -960,6 +989,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
status->ampdu_reference = mstat.ampdu_ref; status->ampdu_reference = mstat.ampdu_ref;
status->device_timestamp = mstat.timestamp; status->device_timestamp = mstat.timestamp;
status->mactime = mstat.timestamp; status->mactime = mstat.timestamp;
status->signal = mt76_rx_signal(&mstat);
if (status->signal <= -128)
status->flag |= RX_FLAG_NO_SIGNAL_VAL;
if (ieee80211_is_beacon(hdr->frame_control) || if (ieee80211_is_beacon(hdr->frame_control) ||
ieee80211_is_probe_resp(hdr->frame_control)) ieee80211_is_probe_resp(hdr->frame_control))
...@@ -1626,7 +1658,7 @@ enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy) ...@@ -1626,7 +1658,7 @@ enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy)
return MT_DFS_STATE_DISABLED; return MT_DFS_STATE_DISABLED;
} }
if (phy->chandef.chan->dfs_state != NL80211_DFS_AVAILABLE) if (!cfg80211_reg_can_beacon(hw->wiphy, &phy->chandef, NL80211_IFTYPE_AP))
return MT_DFS_STATE_CAC; return MT_DFS_STATE_CAC;
return MT_DFS_STATE_ACTIVE; return MT_DFS_STATE_ACTIVE;
......
...@@ -643,11 +643,6 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) ...@@ -643,11 +643,6 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
status->chain_signal[1] = FIELD_GET(MT_RXV4_IB_RSSI1, rxdg3) + status->chain_signal[1] = FIELD_GET(MT_RXV4_IB_RSSI1, rxdg3) +
dev->rssi_offset[1]; dev->rssi_offset[1];
status->signal = status->chain_signal[0];
if (status->chains & BIT(1))
status->signal = max(status->signal,
status->chain_signal[1]);
if (FIELD_GET(MT_RXV1_FRAME_MODE, rxdg0) == 1) if (FIELD_GET(MT_RXV1_FRAME_MODE, rxdg0) == 1)
status->bw = RATE_INFO_BW_40; status->bw = RATE_INFO_BW_40;
......
...@@ -443,11 +443,16 @@ mt7615_ext_mac_addr_read(struct file *file, char __user *userbuf, ...@@ -443,11 +443,16 @@ mt7615_ext_mac_addr_read(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct mt7615_dev *dev = file->private_data; struct mt7615_dev *dev = file->private_data;
char buf[32 * ((ETH_ALEN * 3) + 4) + 1]; u32 len = 32 * ((ETH_ALEN * 3) + 4) + 1;
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
char *buf;
int ofs = 0; int ofs = 0;
int i; int i;
buf = kzalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
if (!(dev->muar_mask & BIT(i))) if (!(dev->muar_mask & BIT(i)))
continue; continue;
...@@ -458,10 +463,13 @@ mt7615_ext_mac_addr_read(struct file *file, char __user *userbuf, ...@@ -458,10 +463,13 @@ mt7615_ext_mac_addr_read(struct file *file, char __user *userbuf,
put_unaligned_le32(mt76_rr(dev, MT_WF_RMAC_MAR0), addr); put_unaligned_le32(mt76_rr(dev, MT_WF_RMAC_MAR0), addr);
put_unaligned_le16((mt76_rr(dev, MT_WF_RMAC_MAR1) & put_unaligned_le16((mt76_rr(dev, MT_WF_RMAC_MAR1) &
MT_WF_RMAC_MAR1_ADDR), addr + 4); MT_WF_RMAC_MAR1_ADDR), addr + 4);
ofs += snprintf(buf + ofs, sizeof(buf) - ofs, "%d=%pM\n", i, addr); ofs += snprintf(buf + ofs, len - ofs, "%d=%pM\n", i, addr);
} }
return simple_read_from_buffer(userbuf, count, ppos, buf, ofs); ofs = simple_read_from_buffer(userbuf, count, ppos, buf, ofs);
kfree(buf);
return ofs;
} }
static ssize_t static ssize_t
......
...@@ -259,7 +259,7 @@ static int mt7615_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) ...@@ -259,7 +259,7 @@ static int mt7615_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
struct ieee80211_hdr hdr; struct ieee80211_hdr hdr;
__le32 qos_ctrl, ht_ctrl; u16 frame_control;
if (FIELD_GET(MT_RXD1_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[1])) != if (FIELD_GET(MT_RXD1_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[1])) !=
MT_RXD1_NORMAL_U2M) MT_RXD1_NORMAL_U2M)
...@@ -275,16 +275,15 @@ static int mt7615_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) ...@@ -275,16 +275,15 @@ static int mt7615_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
/* store the info from RXD and ethhdr to avoid being overridden */ /* store the info from RXD and ethhdr to avoid being overridden */
hdr.frame_control = FIELD_GET(MT_RXD4_FRAME_CONTROL, rxd[4]); frame_control = le32_get_bits(rxd[4], MT_RXD4_FRAME_CONTROL);
hdr.seq_ctrl = FIELD_GET(MT_RXD6_SEQ_CTRL, rxd[6]); hdr.frame_control = cpu_to_le16(frame_control);
qos_ctrl = FIELD_GET(MT_RXD6_QOS_CTL, rxd[6]); hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[6], MT_RXD6_SEQ_CTRL));
ht_ctrl = FIELD_GET(MT_RXD7_HT_CONTROL, rxd[7]);
hdr.duration_id = 0; hdr.duration_id = 0;
ether_addr_copy(hdr.addr1, vif->addr); ether_addr_copy(hdr.addr1, vif->addr);
ether_addr_copy(hdr.addr2, sta->addr); ether_addr_copy(hdr.addr2, sta->addr);
switch (le16_to_cpu(hdr.frame_control) & switch (frame_control & (IEEE80211_FCTL_TODS |
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { IEEE80211_FCTL_FROMDS)) {
case 0: case 0:
ether_addr_copy(hdr.addr3, vif->bss_conf.bssid); ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
break; break;
...@@ -306,15 +305,23 @@ static int mt7615_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) ...@@ -306,15 +305,23 @@ static int mt7615_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) || if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) ||
eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX)) eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX))
ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header); ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
else if (eth_hdr->h_proto >= cpu_to_be16(ETH_P_802_3_MIN)) else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN)
ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header); ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
else else
skb_pull(skb, 2); skb_pull(skb, 2);
if (ieee80211_has_order(hdr.frame_control)) if (ieee80211_has_order(hdr.frame_control))
memcpy(skb_push(skb, 2), &ht_ctrl, 2); memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[7],
if (ieee80211_is_data_qos(hdr.frame_control)) IEEE80211_HT_CTL_LEN);
memcpy(skb_push(skb, 2), &qos_ctrl, 2);
if (ieee80211_is_data_qos(hdr.frame_control)) {
__le16 qos_ctrl;
qos_ctrl = cpu_to_le16(le32_get_bits(rxd[6], MT_RXD6_QOS_CTL));
memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl,
IEEE80211_QOS_CTL_LEN);
}
if (ieee80211_has_a4(hdr.frame_control)) if (ieee80211_has_a4(hdr.frame_control))
memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr)); memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
else else
...@@ -569,15 +576,6 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb) ...@@ -569,15 +576,6 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
status->chain_signal[1] = to_rssi(MT_RXV4_RCPI1, rxdg3); status->chain_signal[1] = to_rssi(MT_RXV4_RCPI1, rxdg3);
status->chain_signal[2] = to_rssi(MT_RXV4_RCPI2, rxdg3); status->chain_signal[2] = to_rssi(MT_RXV4_RCPI2, rxdg3);
status->chain_signal[3] = to_rssi(MT_RXV4_RCPI3, rxdg3); status->chain_signal[3] = to_rssi(MT_RXV4_RCPI3, rxdg3);
status->signal = status->chain_signal[0];
for (i = 1; i < hweight8(mphy->antenna_mask); i++) {
if (!(status->chains & BIT(i)))
continue;
status->signal = max(status->signal,
status->chain_signal[i]);
}
mt7615_mac_fill_tm_rx(mphy->priv, rxd); mt7615_mac_fill_tm_rx(mphy->priv, rxd);
...@@ -1862,7 +1860,7 @@ mt7615_mac_adjust_sensitivity(struct mt7615_phy *phy, ...@@ -1862,7 +1860,7 @@ mt7615_mac_adjust_sensitivity(struct mt7615_phy *phy,
struct mt7615_dev *dev = phy->dev; struct mt7615_dev *dev = phy->dev;
int false_cca = ofdm ? phy->false_cca_ofdm : phy->false_cca_cck; int false_cca = ofdm ? phy->false_cca_ofdm : phy->false_cca_cck;
bool ext_phy = phy != &dev->phy; bool ext_phy = phy != &dev->phy;
u16 def_th = ofdm ? -98 : -110; s16 def_th = ofdm ? -98 : -110;
bool update = false; bool update = false;
s8 *sensitivity; s8 *sensitivity;
int signal; int signal;
......
...@@ -431,6 +431,29 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ...@@ -431,6 +431,29 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return err; return err;
} }
static int mt7615_set_sar_specs(struct ieee80211_hw *hw,
const struct cfg80211_sar_specs *sar)
{
struct mt7615_phy *phy = mt7615_hw_phy(hw);
int err;
if (!cfg80211_chandef_valid(&phy->mt76->chandef))
return -EINVAL;
err = mt76_init_sar_power(hw, sar);
if (err)
return err;
if (mt7615_firmware_offload(phy->dev))
return mt76_connac_mcu_set_rate_txpower(phy->mt76);
ieee80211_stop_queues(hw);
err = mt7615_set_channel(phy);
ieee80211_wake_queues(hw);
return err;
}
static int mt7615_config(struct ieee80211_hw *hw, u32 changed) static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
{ {
struct mt7615_dev *dev = mt7615_hw_dev(hw); struct mt7615_dev *dev = mt7615_hw_dev(hw);
...@@ -1333,6 +1356,7 @@ const struct ieee80211_ops mt7615_ops = { ...@@ -1333,6 +1356,7 @@ const struct ieee80211_ops mt7615_ops = {
.set_wakeup = mt7615_set_wakeup, .set_wakeup = mt7615_set_wakeup,
.set_rekey_data = mt7615_set_rekey_data, .set_rekey_data = mt7615_set_rekey_data,
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
.set_sar_specs = mt7615_set_sar_specs,
}; };
EXPORT_SYMBOL_GPL(mt7615_ops); EXPORT_SYMBOL_GPL(mt7615_ops);
......
...@@ -2020,7 +2020,7 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku) ...@@ -2020,7 +2020,7 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)
struct mt76_power_limits limits; struct mt76_power_limits limits;
s8 *limits_array = (s8 *)&limits; s8 *limits_array = (s8 *)&limits;
int n_chains = hweight8(mphy->antenna_mask); int n_chains = hweight8(mphy->antenna_mask);
int tx_power; int tx_power = hw->conf.power_level * 2;
int i; int i;
static const u8 sku_mapping[] = { static const u8 sku_mapping[] = {
#define SKU_FIELD(_type, _field) \ #define SKU_FIELD(_type, _field) \
...@@ -2077,9 +2077,8 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku) ...@@ -2077,9 +2077,8 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)
#undef SKU_FIELD #undef SKU_FIELD
}; };
tx_power = hw->conf.power_level * 2 - tx_power = mt76_get_sar_power(mphy, mphy->chandef.chan, tx_power);
mt76_tx_power_nss_delta(n_chains); tx_power -= mt76_tx_power_nss_delta(n_chains);
tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan, tx_power = mt76_get_rate_power_limits(mphy, mphy->chandef.chan,
&limits, tx_power); &limits, tx_power);
mphy->txpower_cur = tx_power; mphy->txpower_cur = tx_power;
...@@ -2152,10 +2151,12 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd) ...@@ -2152,10 +2151,12 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
.center_chan2 = ieee80211_frequency_to_channel(freq2), .center_chan2 = ieee80211_frequency_to_channel(freq2),
}; };
if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) if (cmd == MCU_EXT_CMD(SET_RX_PATH))
req.switch_reason = CH_SWITCH_NORMAL;
else if (phy->mt76->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD; req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
else if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) && else if (!cfg80211_reg_can_beacon(phy->mt76->hw->wiphy, chandef,
chandef->chan->dfs_state != NL80211_DFS_AVAILABLE) NL80211_IFTYPE_AP))
req.switch_reason = CH_SWITCH_DFS; req.switch_reason = CH_SWITCH_DFS;
else else
req.switch_reason = CH_SWITCH_NORMAL; req.switch_reason = CH_SWITCH_NORMAL;
......
...@@ -117,6 +117,11 @@ static inline bool is_mt7916(struct mt76_dev *dev) ...@@ -117,6 +117,11 @@ static inline bool is_mt7916(struct mt76_dev *dev)
return mt76_chip(dev) == 0x7906; return mt76_chip(dev) == 0x7906;
} }
static inline bool is_mt7986(struct mt76_dev *dev)
{
return mt76_chip(dev) == 0x7986;
}
static inline bool is_mt7622(struct mt76_dev *dev) static inline bool is_mt7622(struct mt76_dev *dev)
{ {
if (!IS_ENABLED(CONFIG_MT7622_WMAC)) if (!IS_ENABLED(CONFIG_MT7622_WMAC))
......
...@@ -1501,7 +1501,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, ...@@ -1501,7 +1501,6 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
int ext_channels_num = max_t(int, sreq->n_channels - 32, 0); int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
struct ieee80211_channel **scan_list = sreq->channels; struct ieee80211_channel **scan_list = sreq->channels;
struct mt76_dev *mdev = phy->dev; struct mt76_dev *mdev = phy->dev;
bool ext_phy = phy == mdev->phy2;
struct mt76_connac_mcu_scan_channel *chan; struct mt76_connac_mcu_scan_channel *chan;
struct mt76_connac_hw_scan_req *req; struct mt76_connac_hw_scan_req *req;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1515,7 +1514,7 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, ...@@ -1515,7 +1514,7 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req)); req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
req->seq_num = mvif->scan_seq_num | ext_phy << 7; req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
req->bss_idx = mvif->idx; req->bss_idx = mvif->idx;
req->scan_type = sreq->n_ssids ? 1 : 0; req->scan_type = sreq->n_ssids ? 1 : 0;
req->probe_req_num = sreq->n_ssids ? 2 : 0; req->probe_req_num = sreq->n_ssids ? 2 : 0;
...@@ -1623,7 +1622,6 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy, ...@@ -1623,7 +1622,6 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
struct mt76_connac_mcu_scan_channel *chan; struct mt76_connac_mcu_scan_channel *chan;
struct mt76_connac_sched_scan_req *req; struct mt76_connac_sched_scan_req *req;
struct mt76_dev *mdev = phy->dev; struct mt76_dev *mdev = phy->dev;
bool ext_phy = phy == mdev->phy2;
struct cfg80211_match_set *match; struct cfg80211_match_set *match;
struct cfg80211_ssid *ssid; struct cfg80211_ssid *ssid;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -1637,7 +1635,7 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy, ...@@ -1637,7 +1635,7 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req)); req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
req->version = 1; req->version = 1;
req->seq_num = mvif->scan_seq_num | ext_phy << 7; req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) { if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac
...@@ -2656,7 +2654,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv); ...@@ -2656,7 +2654,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv);
int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct mt76_phy *phy, u8 wlan_idx, struct mt76_phy *phy, u16 wlan_idx,
bool enable) bool enable)
{ {
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
......
...@@ -1642,7 +1642,7 @@ void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb, ...@@ -1642,7 +1642,7 @@ void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb,
int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct mt76_phy *phy, u8 wlan_idx, struct mt76_phy *phy, u16 wlan_idx,
bool enable); bool enable);
void mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif, void mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
struct ieee80211_sta *sta); struct ieee80211_sta *sta);
......
...@@ -860,9 +860,7 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb, ...@@ -860,9 +860,7 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
status->chain_signal[1] = mt76x02_mac_get_rssi(dev, status->chain_signal[1] = mt76x02_mac_get_rssi(dev,
rxwi->rssi[1], rxwi->rssi[1],
1); 1);
signal = max_t(s8, signal, status->chain_signal[1]);
} }
status->signal = signal;
status->freq = dev->mphy.chandef.chan->center_freq; status->freq = dev->mphy.chandef.chan->center_freq;
status->band = dev->mphy.chandef.chan->band; status->band = dev->mphy.chandef.chan->band;
......
...@@ -12,3 +12,13 @@ config MT7915E ...@@ -12,3 +12,13 @@ config MT7915E
OFDMA, spatial reuse and dual carrier modulation. OFDMA, spatial reuse and dual carrier modulation.
To compile this driver as a module, choose M here. To compile this driver as a module, choose M here.
config MT7986_WMAC
bool "MT7986 (SoC) WMAC support"
depends on MT7915E
depends on ARCH_MEDIATEK || COMPILE_TEST
select REGMAP
help
This adds support for the built-in WMAC on MT7986 SoC device
which has the same feature set as a MT7915, but enables 6E
support.
...@@ -6,3 +6,4 @@ mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \ ...@@ -6,3 +6,4 @@ mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
debugfs.o mmio.o debugfs.o mmio.o
mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
mt7915e-$(CONFIG_MT7986_WMAC) += soc.o
\ No newline at end of file
...@@ -548,12 +548,12 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, ...@@ -548,12 +548,12 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
/* Tx ampdu stat */ /* Tx ampdu stat */
for (i = 0; i < ARRAY_SIZE(range); i++) for (i = 0; i < ARRAY_SIZE(range); i++)
range[i] = mt76_rr(dev, MT_MIB_ARNG(ext_phy, i)); range[i] = mt76_rr(dev, MT_MIB_ARNG(phy->band_idx, i));
for (i = 0; i < ARRAY_SIZE(bound); i++) for (i = 0; i < ARRAY_SIZE(bound); i++)
bound[i] = MT_MIB_ARNCR_RANGE(range[i / 4], i % 4) + 1; bound[i] = MT_MIB_ARNCR_RANGE(range[i / 4], i % 4) + 1;
seq_printf(file, "\nPhy %d\n", ext_phy); seq_printf(file, "\nPhy %d, Phy band %d\n", ext_phy, phy->band_idx);
seq_printf(file, "Length: %8d | ", bound[0]); seq_printf(file, "Length: %8d | ", bound[0]);
for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
...@@ -561,7 +561,7 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy, ...@@ -561,7 +561,7 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
bound[i] + 1, bound[i + 1]); bound[i] + 1, bound[i + 1]);
seq_puts(file, "\nCount: "); seq_puts(file, "\nCount: ");
n = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0; n = phy->band_idx ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
for (i = 0; i < ARRAY_SIZE(bound); i++) for (i = 0; i < ARRAY_SIZE(bound); i++)
seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + n]); seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + n]);
seq_puts(file, "\n"); seq_puts(file, "\n");
...@@ -898,7 +898,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) ...@@ -898,7 +898,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy)
debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir, debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir,
mt7915_twt_stats); mt7915_twt_stats);
debugfs_create_file("ser_trigger", 0200, dir, dev, &fops_ser_trigger); debugfs_create_file("ser_trigger", 0200, dir, dev, &fops_ser_trigger);
if (!dev->dbdc_support || ext_phy) { if (!dev->dbdc_support || phy->band_idx) {
debugfs_create_u32("dfs_hw_pattern", 0400, dir, debugfs_create_u32("dfs_hw_pattern", 0400, dir,
&dev->hw_pattern); &dev->hw_pattern);
debugfs_create_file("radar_trigger", 0200, dir, dev, debugfs_create_file("radar_trigger", 0200, dir, dev,
...@@ -947,13 +947,13 @@ void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int ...@@ -947,13 +947,13 @@ void mt7915_debugfs_rx_fw_monitor(struct mt7915_dev *dev, const void *data, int
__le16 len; __le16 len;
} hdr = { } hdr = {
.magic = cpu_to_le32(FW_BIN_LOG_MAGIC), .magic = cpu_to_le32(FW_BIN_LOG_MAGIC),
.msg_type = PKT_TYPE_RX_FW_MONITOR, .msg_type = cpu_to_le16(PKT_TYPE_RX_FW_MONITOR),
}; };
if (!dev->relay_fwlog) if (!dev->relay_fwlog)
return; return;
hdr.timestamp = mt76_rr(dev, MT_LPON_FRCR(0)); hdr.timestamp = cpu_to_le32(mt76_rr(dev, MT_LPON_FRCR(0)));
hdr.len = *(__le16 *)data; hdr.len = *(__le16 *)data;
mt7915_debugfs_write_fwlog(dev, &hdr, sizeof(hdr), data, len); mt7915_debugfs_write_fwlog(dev, &hdr, sizeof(hdr), data, len);
} }
......
...@@ -310,10 +310,12 @@ static int mt7915_dma_enable(struct mt7915_dev *dev) ...@@ -310,10 +310,12 @@ static int mt7915_dma_enable(struct mt7915_dev *dev)
/* enable interrupts for TX/RX rings */ /* enable interrupts for TX/RX rings */
irq_mask = MT_INT_RX_DONE_MCU | irq_mask = MT_INT_RX_DONE_MCU |
MT_INT_TX_DONE_MCU | MT_INT_TX_DONE_MCU |
MT_INT_MCU_CMD | MT_INT_MCU_CMD;
MT_INT_BAND0_RX_DONE;
if (dev->dbdc_support) if (!dev->phy.band_idx)
irq_mask |= MT_INT_BAND0_RX_DONE;
if (dev->dbdc_support || dev->phy.band_idx)
irq_mask |= MT_INT_BAND1_RX_DONE; irq_mask |= MT_INT_BAND1_RX_DONE;
mt7915_irq_enable(dev, irq_mask); mt7915_irq_enable(dev, irq_mask);
...@@ -338,7 +340,7 @@ int mt7915_dma_init(struct mt7915_dev *dev) ...@@ -338,7 +340,7 @@ int mt7915_dma_init(struct mt7915_dev *dev)
/* init tx queue */ /* init tx queue */
ret = mt7915_init_tx_queues(&dev->phy, ret = mt7915_init_tx_queues(&dev->phy,
MT_TXQ_ID(0), MT_TXQ_ID(dev->phy.band_idx),
MT7915_TX_RING_SIZE, MT7915_TX_RING_SIZE,
MT_TXQ_RING_BASE(0)); MT_TXQ_RING_BASE(0));
if (ret) if (ret)
...@@ -387,13 +389,15 @@ int mt7915_dma_init(struct mt7915_dev *dev) ...@@ -387,13 +389,15 @@ int mt7915_dma_init(struct mt7915_dev *dev)
return ret; return ret;
/* rx data queue for band0 */ /* rx data queue for band0 */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], if (!dev->phy.band_idx) {
MT_RXQ_ID(MT_RXQ_MAIN), ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
MT7915_RX_RING_SIZE, MT_RXQ_ID(MT_RXQ_MAIN),
MT_RX_BUF_SIZE, MT7915_RX_RING_SIZE,
MT_RXQ_RING_BASE(MT_RXQ_MAIN)); MT_RX_BUF_SIZE,
if (ret) MT_RXQ_RING_BASE(MT_RXQ_MAIN));
return ret; if (ret)
return ret;
}
/* tx free notify event from WA for band0 */ /* tx free notify event from WA for band0 */
if (!is_mt7915(mdev)) { if (!is_mt7915(mdev)) {
...@@ -406,7 +410,7 @@ int mt7915_dma_init(struct mt7915_dev *dev) ...@@ -406,7 +410,7 @@ int mt7915_dma_init(struct mt7915_dev *dev)
return ret; return ret;
} }
if (dev->dbdc_support) { if (dev->dbdc_support || dev->phy.band_idx) {
/* rx data queue for band1 */ /* rx data queue for band1 */
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT], ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT],
MT_RXQ_ID(MT_RXQ_EXT), MT_RXQ_ID(MT_RXQ_EXT),
......
...@@ -36,27 +36,48 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev) ...@@ -36,27 +36,48 @@ static int mt7915_check_eeprom(struct mt7915_dev *dev)
switch (val) { switch (val) {
case 0x7915: case 0x7915:
case 0x7916: case 0x7916:
case 0x7986:
return 0; return 0;
default: default:
return -EINVAL; return -EINVAL;
} }
} }
static char *mt7915_eeprom_name(struct mt7915_dev *dev)
{
switch (mt76_chip(&dev->mt76)) {
case 0x7915:
return dev->dbdc_support ?
MT7915_EEPROM_DEFAULT_DBDC : MT7915_EEPROM_DEFAULT;
case 0x7986:
switch (mt7915_check_adie(dev, true)) {
case MT7976_ONE_ADIE_DBDC:
return MT7986_EEPROM_MT7976_DEFAULT_DBDC;
case MT7975_ONE_ADIE:
return MT7986_EEPROM_MT7975_DEFAULT;
case MT7976_ONE_ADIE:
return MT7986_EEPROM_MT7976_DEFAULT;
case MT7975_DUAL_ADIE:
return MT7986_EEPROM_MT7975_DUAL_DEFAULT;
case MT7976_DUAL_ADIE:
return MT7986_EEPROM_MT7976_DUAL_DEFAULT;
default:
break;
}
return NULL;
default:
return MT7916_EEPROM_DEFAULT;
}
}
static int static int
mt7915_eeprom_load_default(struct mt7915_dev *dev) mt7915_eeprom_load_default(struct mt7915_dev *dev)
{ {
char *default_bin = MT7915_EEPROM_DEFAULT;
u8 *eeprom = dev->mt76.eeprom.data; u8 *eeprom = dev->mt76.eeprom.data;
const struct firmware *fw = NULL; const struct firmware *fw = NULL;
int ret; int ret;
if (dev->dbdc_support) ret = request_firmware(&fw, mt7915_eeprom_name(dev), dev->mt76.dev);
default_bin = MT7915_EEPROM_DEFAULT_DBDC;
if (!is_mt7915(&dev->mt76))
default_bin = MT7916_EEPROM_DEFAULT;
ret = request_firmware(&fw, default_bin, dev->mt76.dev);
if (ret) if (ret)
return ret; return ret;
...@@ -109,14 +130,14 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev) ...@@ -109,14 +130,14 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
{ {
struct mt7915_dev *dev = phy->dev; struct mt7915_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
u8 *eeprom = dev->mt76.eeprom.data; u8 *eeprom = dev->mt76.eeprom.data;
u32 val; u32 val;
val = eeprom[MT_EE_WIFI_CONF + ext_phy]; val = eeprom[MT_EE_WIFI_CONF + phy->band_idx];
val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val); val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) if (val == MT_EE_BAND_SEL_DEFAULT &&
val = ext_phy ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ; (!is_mt7915(&dev->mt76) || dev->dbdc_support))
val = phy->band_idx ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
switch (val) { switch (val) {
case MT_EE_BAND_SEL_5GHZ: case MT_EE_BAND_SEL_5GHZ:
...@@ -135,7 +156,7 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) ...@@ -135,7 +156,7 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev, void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
struct mt7915_phy *phy) struct mt7915_phy *phy)
{ {
u8 nss, nss_band, *eeprom = dev->mt76.eeprom.data; u8 nss, nss_band, nss_band_max, *eeprom = dev->mt76.eeprom.data;
struct mt76_phy *mphy = phy->mt76; struct mt76_phy *mphy = phy->mt76;
bool ext_phy = phy != &dev->phy; bool ext_phy = phy != &dev->phy;
...@@ -147,7 +168,7 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev, ...@@ -147,7 +168,7 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
eeprom[MT_EE_WIFI_CONF]); eeprom[MT_EE_WIFI_CONF]);
} else { } else {
nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH, nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
eeprom[MT_EE_WIFI_CONF + ext_phy]); eeprom[MT_EE_WIFI_CONF + phy->band_idx]);
} }
if (!nss || nss > 4) if (!nss || nss > 4)
...@@ -155,32 +176,42 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev, ...@@ -155,32 +176,42 @@ void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
/* read tx/rx stream */ /* read tx/rx stream */
nss_band = nss; nss_band = nss;
if (dev->dbdc_support) { if (dev->dbdc_support) {
if (is_mt7915(&dev->mt76)) { if (is_mt7915(&dev->mt76)) {
nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0, nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
eeprom[MT_EE_WIFI_CONF + 3]); eeprom[MT_EE_WIFI_CONF + 3]);
if (ext_phy) if (phy->band_idx)
nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1, nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
eeprom[MT_EE_WIFI_CONF + 3]); eeprom[MT_EE_WIFI_CONF + 3]);
} else { } else {
nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM, nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
eeprom[MT_EE_WIFI_CONF + 2 + ext_phy]); eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]);
} }
if (!nss_band || nss_band > 2) nss_band_max = is_mt7986(&dev->mt76) ?
nss_band = 2; MT_EE_NSS_MAX_DBDC_MA7986 : MT_EE_NSS_MAX_DBDC_MA7915;
} else {
nss_band_max = is_mt7986(&dev->mt76) ?
MT_EE_NSS_MAX_MA7986 : MT_EE_NSS_MAX_MA7915;
} }
if (!nss_band || nss_band > nss_band_max)
nss_band = nss_band_max;
if (nss_band > nss) { if (nss_band > nss) {
dev_err(dev->mt76.dev, dev_warn(dev->mt76.dev,
"nss mismatch, nss(%d) nss_band(%d) ext_phy(%d)\n", "nss mismatch, nss(%d) nss_band(%d) band(%d) ext_phy(%d)\n",
nss, nss_band, ext_phy); nss, nss_band, phy->band_idx, ext_phy);
nss = nss_band; nss = nss_band;
} }
mphy->chainmask = ext_phy ? (BIT(nss_band) - 1) << 2 : (BIT(nss_band) - 1); mphy->chainmask = BIT(nss) - 1;
mphy->antenna_mask = BIT(hweight8(mphy->chainmask)) - 1; if (ext_phy)
mphy->chainmask <<= dev->chainshift;
mphy->antenna_mask = BIT(nss_band) - 1;
dev->chainmask |= mphy->chainmask; dev->chainmask |= mphy->chainmask;
dev->chainshift = hweight8(dev->mphy.chainmask);
} }
int mt7915_eeprom_init(struct mt7915_dev *dev) int mt7915_eeprom_init(struct mt7915_dev *dev)
...@@ -226,7 +257,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev, ...@@ -226,7 +257,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
if (chan->band == NL80211_BAND_2GHZ) { if (chan->band == NL80211_BAND_2GHZ) {
u32 power = is_mt7915(&dev->mt76) ? u32 power = is_mt7915(&dev->mt76) ?
MT_EE_TX0_POWER_2G : MT_EE_TX0_POWER_2G_V2; MT_EE_TX0_POWER_2G : MT_EE_TX0_POWER_2G_V2;
index = power + chain_idx * 3; index = power + chain_idx * 3;
target_power = eeprom[index]; target_power = eeprom[index];
...@@ -236,7 +267,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev, ...@@ -236,7 +267,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev,
} else { } else {
int group = mt7915_get_channel_group(chan->hw_value); int group = mt7915_get_channel_group(chan->hw_value);
u32 power = is_mt7915(&dev->mt76) ? u32 power = is_mt7915(&dev->mt76) ?
MT_EE_TX0_POWER_5G : MT_EE_TX0_POWER_5G_V2; MT_EE_TX0_POWER_5G : MT_EE_TX0_POWER_5G_V2;
index = power + chain_idx * 12; index = power + chain_idx * 12;
target_power = eeprom[index + group]; target_power = eeprom[index + group];
...@@ -256,10 +287,10 @@ s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band) ...@@ -256,10 +287,10 @@ s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band)
u32 rate_2g, rate_5g; u32 rate_2g, rate_5g;
rate_2g = is_mt7915(&dev->mt76) ? rate_2g = is_mt7915(&dev->mt76) ?
MT_EE_RATE_DELTA_2G : MT_EE_RATE_DELTA_2G_V2; MT_EE_RATE_DELTA_2G : MT_EE_RATE_DELTA_2G_V2;
rate_5g = is_mt7915(&dev->mt76) ? rate_5g = is_mt7915(&dev->mt76) ?
MT_EE_RATE_DELTA_5G : MT_EE_RATE_DELTA_5G_V2; MT_EE_RATE_DELTA_5G : MT_EE_RATE_DELTA_5G_V2;
if (band == NL80211_BAND_2GHZ) if (band == NL80211_BAND_2GHZ)
val = eeprom[rate_2g]; val = eeprom[rate_2g];
......
...@@ -56,6 +56,19 @@ enum mt7915_eeprom_field { ...@@ -56,6 +56,19 @@ enum mt7915_eeprom_field {
#define MT_EE_RATE_DELTA_SIGN BIT(6) #define MT_EE_RATE_DELTA_SIGN BIT(6)
#define MT_EE_RATE_DELTA_EN BIT(7) #define MT_EE_RATE_DELTA_EN BIT(7)
#define MT_EE_NSS_MAX_MA7915 4
#define MT_EE_NSS_MAX_DBDC_MA7915 2
#define MT_EE_NSS_MAX_MA7986 4
#define MT_EE_NSS_MAX_DBDC_MA7986 4
enum mt7915_adie_sku {
MT7976_ONE_ADIE_DBDC = 0x7,
MT7975_ONE_ADIE = 0x8,
MT7976_ONE_ADIE = 0xa,
MT7975_DUAL_ADIE = 0xd,
MT7976_DUAL_ADIE = 0xf,
};
enum mt7915_eeprom_band { enum mt7915_eeprom_band {
MT_EE_BAND_SEL_DEFAULT, MT_EE_BAND_SEL_DEFAULT,
MT_EE_BAND_SEL_5GHZ, MT_EE_BAND_SEL_5GHZ,
......
...@@ -50,15 +50,22 @@ static ssize_t mt7915_thermal_temp_show(struct device *dev, ...@@ -50,15 +50,22 @@ static ssize_t mt7915_thermal_temp_show(struct device *dev,
int i = to_sensor_dev_attr(attr)->index; int i = to_sensor_dev_attr(attr)->index;
int temperature; int temperature;
if (i) switch (i) {
return sprintf(buf, "%u\n", phy->throttle_temp[i - 1] * 1000); case 0:
temperature = mt7915_mcu_get_temperature(phy);
temperature = mt7915_mcu_get_temperature(phy); if (temperature < 0)
if (temperature < 0) return temperature;
return temperature; /* display in millidegree celcius */
return sprintf(buf, "%u\n", temperature * 1000);
/* display in millidegree celcius */ case 1:
return sprintf(buf, "%u\n", temperature * 1000); case 2:
return sprintf(buf, "%u\n",
phy->throttle_temp[i - 1] * 1000);
case 3:
return sprintf(buf, "%hhu\n", phy->throttle_state);
default:
return -EINVAL;
}
} }
static ssize_t mt7915_thermal_temp_store(struct device *dev, static ssize_t mt7915_thermal_temp_store(struct device *dev,
...@@ -84,11 +91,13 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev, ...@@ -84,11 +91,13 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev,
static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7915_thermal_temp, 0); static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7915_thermal_temp, 0);
static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7915_thermal_temp, 1); static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7915_thermal_temp, 1);
static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7915_thermal_temp, 2); static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7915_thermal_temp, 2);
static SENSOR_DEVICE_ATTR_RO(throttle1, mt7915_thermal_temp, 3);
static struct attribute *mt7915_hwmon_attrs[] = { static struct attribute *mt7915_hwmon_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr, &sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr, &sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_throttle1.dev_attr.attr,
NULL, NULL,
}; };
ATTRIBUTE_GROUPS(mt7915_hwmon); ATTRIBUTE_GROUPS(mt7915_hwmon);
...@@ -97,7 +106,7 @@ static int ...@@ -97,7 +106,7 @@ static int
mt7915_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev, mt7915_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
unsigned long *state) unsigned long *state)
{ {
*state = MT7915_THERMAL_THROTTLE_MAX; *state = MT7915_CDEV_THROTTLE_MAX;
return 0; return 0;
} }
...@@ -108,7 +117,7 @@ mt7915_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev, ...@@ -108,7 +117,7 @@ mt7915_thermal_get_cur_throttle_state(struct thermal_cooling_device *cdev,
{ {
struct mt7915_phy *phy = cdev->devdata; struct mt7915_phy *phy = cdev->devdata;
*state = phy->throttle_state; *state = phy->cdev_state;
return 0; return 0;
} }
...@@ -118,22 +127,27 @@ mt7915_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev, ...@@ -118,22 +127,27 @@ mt7915_thermal_set_cur_throttle_state(struct thermal_cooling_device *cdev,
unsigned long state) unsigned long state)
{ {
struct mt7915_phy *phy = cdev->devdata; struct mt7915_phy *phy = cdev->devdata;
u8 throttling = MT7915_THERMAL_THROTTLE_MAX - state;
int ret; int ret;
if (state > MT7915_THERMAL_THROTTLE_MAX) if (state > MT7915_CDEV_THROTTLE_MAX)
return -EINVAL; return -EINVAL;
if (phy->throttle_temp[0] > phy->throttle_temp[1]) if (phy->throttle_temp[0] > phy->throttle_temp[1])
return 0; return 0;
if (state == phy->throttle_state) if (state == phy->cdev_state)
return 0; return 0;
ret = mt7915_mcu_set_thermal_throttling(phy, state); /*
* cooling_device convention: 0 = no cooling, more = more cooling
* mcu convention: 1 = max cooling, more = less cooling
*/
ret = mt7915_mcu_set_thermal_throttling(phy, throttling);
if (ret) if (ret)
return ret; return ret;
phy->throttle_state = state; phy->cdev_state = state;
return 0; return 0;
} }
...@@ -186,7 +200,8 @@ static int mt7915_thermal_init(struct mt7915_phy *phy) ...@@ -186,7 +200,8 @@ static int mt7915_thermal_init(struct mt7915_phy *phy)
phy->throttle_temp[0] = 110; phy->throttle_temp[0] = 110;
phy->throttle_temp[1] = 120; phy->throttle_temp[1] = 120;
return 0; return mt7915_mcu_set_thermal_throttling(phy,
MT7915_THERMAL_THROTTLE_MAX);
} }
static void mt7915_led_set_config(struct led_classdev *led_cdev, static void mt7915_led_set_config(struct led_classdev *led_cdev,
...@@ -486,6 +501,9 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev) ...@@ -486,6 +501,9 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev)
phy->dev = dev; phy->dev = dev;
phy->mt76 = mphy; phy->mt76 = mphy;
/* Bind main phy to band0 and ext_phy to band1 for dbdc case */
phy->band_idx = 1;
INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work); INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work);
mt7915_eeprom_parse_hw_cap(dev, phy); mt7915_eeprom_parse_hw_cap(dev, phy);
...@@ -505,7 +523,7 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev) ...@@ -505,7 +523,7 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev)
/* init wiphy according to mphy and phy */ /* init wiphy according to mphy and phy */
mt7915_init_wiphy(mphy->hw); mt7915_init_wiphy(mphy->hw);
ret = mt7915_init_tx_queues(phy, MT_TXQ_ID(1), ret = mt7915_init_tx_queues(phy, MT_TXQ_ID(phy->band_idx),
MT7915_TX_RING_SIZE, MT7915_TX_RING_SIZE,
MT_TXQ_RING_BASE(1)); MT_TXQ_RING_BASE(1));
if (ret) if (ret)
...@@ -582,6 +600,12 @@ static void mt7915_wfsys_reset(struct mt7915_dev *dev) ...@@ -582,6 +600,12 @@ static void mt7915_wfsys_reset(struct mt7915_dev *dev)
mt76_clear(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE); mt76_clear(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE);
msleep(100); msleep(100);
} else if (is_mt7986(&dev->mt76)) {
mt7986_wmac_disable(dev);
msleep(20);
mt7986_wmac_enable(dev);
msleep(20);
} else { } else {
mt76_set(dev, MT_WF_SUBSYS_RST, 0x1); mt76_set(dev, MT_WF_SUBSYS_RST, 0x1);
msleep(20); msleep(20);
...@@ -591,6 +615,32 @@ static void mt7915_wfsys_reset(struct mt7915_dev *dev) ...@@ -591,6 +615,32 @@ static void mt7915_wfsys_reset(struct mt7915_dev *dev)
} }
} }
static bool mt7915_band_config(struct mt7915_dev *dev)
{
bool ret = true;
dev->phy.band_idx = 0;
if (is_mt7986(&dev->mt76)) {
u32 sku = mt7915_check_adie(dev, true);
/*
* for mt7986, dbdc support is determined by the number
* of adie chips and the main phy is bound to band1 when
* dbdc is disabled.
*/
if (sku == MT7975_ONE_ADIE || sku == MT7976_ONE_ADIE) {
dev->phy.band_idx = 1;
ret = false;
}
} else {
ret = is_mt7915(&dev->mt76) ?
!!(mt76_rr(dev, MT_HW_BOUND) & BIT(5)) : true;
}
return ret;
}
static int mt7915_init_hardware(struct mt7915_dev *dev) static int mt7915_init_hardware(struct mt7915_dev *dev)
{ {
int ret, idx; int ret, idx;
...@@ -599,8 +649,7 @@ static int mt7915_init_hardware(struct mt7915_dev *dev) ...@@ -599,8 +649,7 @@ static int mt7915_init_hardware(struct mt7915_dev *dev)
INIT_WORK(&dev->init_work, mt7915_init_work); INIT_WORK(&dev->init_work, mt7915_init_work);
dev->dbdc_support = is_mt7915(&dev->mt76) ? dev->dbdc_support = mt7915_band_config(dev);
!!(mt76_rr(dev, MT_HW_BOUND) & BIT(5)) : true;
/* If MCU was already running, it is likely in a bad state */ /* If MCU was already running, it is likely in a bad state */
if (mt76_get_field(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE) > if (mt76_get_field(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE) >
...@@ -767,9 +816,17 @@ static int ...@@ -767,9 +816,17 @@ static int
mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
struct ieee80211_sband_iftype_data *data) struct ieee80211_sband_iftype_data *data)
{ {
struct mt7915_dev *dev = phy->dev;
int i, idx = 0, nss = hweight8(phy->mt76->chainmask); int i, idx = 0, nss = hweight8(phy->mt76->chainmask);
u16 mcs_map = 0; u16 mcs_map = 0;
u16 mcs_map_160 = 0; u16 mcs_map_160 = 0;
u8 nss_160;
/* Can do 1/2 of NSS streams in 160Mhz mode for mt7915 */
if (is_mt7915(&dev->mt76) && !dev->dbdc_support)
nss_160 = nss / 2;
else
nss_160 = nss;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (i < nss) if (i < nss)
...@@ -777,8 +834,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, ...@@ -777,8 +834,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
else else
mcs_map |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); mcs_map |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
/* Can do 1/2 of NSS streams in 160Mhz mode. */ if (i < nss_160)
if (i < nss / 2)
mcs_map_160 |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2)); mcs_map_160 |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2));
else else
mcs_map_160 |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2)); mcs_map_160 |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
...@@ -1011,5 +1067,8 @@ void mt7915_unregister_device(struct mt7915_dev *dev) ...@@ -1011,5 +1067,8 @@ void mt7915_unregister_device(struct mt7915_dev *dev)
mt7915_dma_cleanup(dev); mt7915_dma_cleanup(dev);
tasklet_disable(&dev->irq_tasklet); tasklet_disable(&dev->irq_tasklet);
if (is_mt7986(&dev->mt76))
mt7986_wmac_disable(dev);
mt76_free_device(&dev->mt76); mt76_free_device(&dev->mt76);
} }
...@@ -49,7 +49,7 @@ static int mt7915_start(struct ieee80211_hw *hw) ...@@ -49,7 +49,7 @@ static int mt7915_start(struct ieee80211_hw *hw)
mt7915_mac_enable_nf(dev, 0); mt7915_mac_enable_nf(dev, 0);
} }
if (phy != &dev->phy) { if (phy != &dev->phy || phy->band_idx) {
ret = mt76_connac_mcu_set_pm(&dev->mt76, 1, 0); ret = mt76_connac_mcu_set_pm(&dev->mt76, 1, 0);
if (ret) if (ret)
goto out; goto out;
...@@ -217,7 +217,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, ...@@ -217,7 +217,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
} }
mvif->mt76.omac_idx = idx; mvif->mt76.omac_idx = idx;
mvif->phy = phy; mvif->phy = phy;
mvif->mt76.band_idx = ext_phy; mvif->mt76.band_idx = phy->band_idx;
mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP; mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
if (ext_phy) if (ext_phy)
...@@ -235,7 +235,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, ...@@ -235,7 +235,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
INIT_LIST_HEAD(&mvif->sta.rc_list); INIT_LIST_HEAD(&mvif->sta.rc_list);
INIT_LIST_HEAD(&mvif->sta.poll_list); INIT_LIST_HEAD(&mvif->sta.poll_list);
mvif->sta.wcid.idx = idx; mvif->sta.wcid.idx = idx;
mvif->sta.wcid.ext_phy = mvif->mt76.band_idx; mvif->sta.wcid.ext_phy = ext_phy;
mvif->sta.wcid.hw_key_idx = -1; mvif->sta.wcid.hw_key_idx = -1;
mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET; mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET;
mt76_packet_id_init(&mvif->sta.wcid); mt76_packet_id_init(&mvif->sta.wcid);
...@@ -654,6 +654,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, ...@@ -654,6 +654,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
bool ext_phy = mvif->phy != &dev->phy;
int ret, idx; int ret, idx;
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA); idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA);
...@@ -665,7 +666,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, ...@@ -665,7 +666,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
msta->vif = mvif; msta->vif = mvif;
msta->wcid.sta = 1; msta->wcid.sta = 1;
msta->wcid.idx = idx; msta->wcid.idx = idx;
msta->wcid.ext_phy = mvif->mt76.band_idx; msta->wcid.ext_phy = ext_phy;
msta->wcid.tx_info |= MT_WCID_TX_INFO_SET; msta->wcid.tx_info |= MT_WCID_TX_INFO_SET;
msta->jiffies = jiffies; msta->jiffies = jiffies;
...@@ -969,12 +970,9 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) ...@@ -969,12 +970,9 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
phy->mt76->antenna_mask = tx_ant; phy->mt76->antenna_mask = tx_ant;
if (ext_phy) { if (ext_phy)
if (dev->chainmask == 0xf) tx_ant <<= dev->chainshift;
tx_ant <<= 2;
else
tx_ant <<= 1;
}
phy->mt76->chainmask = tx_ant; phy->mt76->chainmask = tx_ant;
mt76_set_stream_caps(phy->mt76, true); mt76_set_stream_caps(phy->mt76, true);
...@@ -1241,7 +1239,6 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, ...@@ -1241,7 +1239,6 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
}; };
struct mib_stats *mib = &phy->mib; struct mib_stats *mib = &phy->mib;
/* See mt7915_ampdu_stat_read_phy, etc */ /* See mt7915_ampdu_stat_read_phy, etc */
bool ext_phy = phy != &dev->phy;
int i, n, ei = 0; int i, n, ei = 0;
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
...@@ -1258,7 +1255,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, ...@@ -1258,7 +1255,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw,
data[ei++] = mib->tx_pkt_ibf_cnt; data[ei++] = mib->tx_pkt_ibf_cnt;
/* Tx ampdu stat */ /* Tx ampdu stat */
n = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0; n = phy->band_idx ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++) for (i = 0; i < 15 /*ARRAY_SIZE(bound)*/; i++)
data[ei++] = dev->mt76.aggr_stats[i + n]; data[ei++] = dev->mt76.aggr_stats[i + n];
......
...@@ -79,6 +79,15 @@ struct mt7915_mcu_csa_notify { ...@@ -79,6 +79,15 @@ struct mt7915_mcu_csa_notify {
u8 rsv; u8 rsv;
} __packed; } __packed;
struct mt7915_mcu_bcc_notify {
struct mt7915_mcu_rxd rxd;
u8 band_idx;
u8 omac_idx;
u8 cca_count;
u8 rsv;
} __packed;
struct mt7915_mcu_rdd_report { struct mt7915_mcu_rdd_report {
struct mt7915_mcu_rxd rxd; struct mt7915_mcu_rxd rxd;
......
...@@ -17,6 +17,11 @@ static const u32 mt7915_reg[] = { ...@@ -17,6 +17,11 @@ static const u32 mt7915_reg[] = {
[INT1_MASK_CSR] = 0xd708c, [INT1_MASK_CSR] = 0xd708c,
[INT_MCU_CMD_SOURCE] = 0xd51f0, [INT_MCU_CMD_SOURCE] = 0xd51f0,
[INT_MCU_CMD_EVENT] = 0x3108, [INT_MCU_CMD_EVENT] = 0x3108,
[WFDMA0_ADDR] = 0xd4000,
[WFDMA0_PCIE1_ADDR] = 0xd8000,
[WFDMA_EXT_CSR_ADDR] = 0xd7000,
[CBTOP1_PHY_END] = 0x77ffffff,
[INFRA_MCU_ADDR_END] = 0x7c3fffff,
}; };
static const u32 mt7916_reg[] = { static const u32 mt7916_reg[] = {
...@@ -26,6 +31,25 @@ static const u32 mt7916_reg[] = { ...@@ -26,6 +31,25 @@ static const u32 mt7916_reg[] = {
[INT1_MASK_CSR] = 0xd8204, [INT1_MASK_CSR] = 0xd8204,
[INT_MCU_CMD_SOURCE] = 0xd41f0, [INT_MCU_CMD_SOURCE] = 0xd41f0,
[INT_MCU_CMD_EVENT] = 0x2108, [INT_MCU_CMD_EVENT] = 0x2108,
[WFDMA0_ADDR] = 0xd4000,
[WFDMA0_PCIE1_ADDR] = 0xd8000,
[WFDMA_EXT_CSR_ADDR] = 0xd7000,
[CBTOP1_PHY_END] = 0x7fffffff,
[INFRA_MCU_ADDR_END] = 0x7c085fff,
};
static const u32 mt7986_reg[] = {
[INT_SOURCE_CSR] = 0x24200,
[INT_MASK_CSR] = 0x24204,
[INT1_SOURCE_CSR] = 0x28200,
[INT1_MASK_CSR] = 0x28204,
[INT_MCU_CMD_SOURCE] = 0x241f0,
[INT_MCU_CMD_EVENT] = 0x54000108,
[WFDMA0_ADDR] = 0x24000,
[WFDMA0_PCIE1_ADDR] = 0x28000,
[WFDMA_EXT_CSR_ADDR] = 0x27000,
[CBTOP1_PHY_END] = 0x7fffffff,
[INFRA_MCU_ADDR_END] = 0x7c085fff,
}; };
static const u32 mt7915_offs[] = { static const u32 mt7915_offs[] = {
...@@ -264,12 +288,69 @@ static const struct __map mt7916_reg_map[] = { ...@@ -264,12 +288,69 @@ static const struct __map mt7916_reg_map[] = {
{ 0x0, 0x0, 0x0 }, /* imply end of search */ { 0x0, 0x0, 0x0 }, /* imply end of search */
}; };
static const struct __map mt7986_reg_map[] = {
{ 0x54000000, 0x402000, 0x1000 }, /* WFDMA_0 (PCIE0 MCU DMA0) */
{ 0x55000000, 0x403000, 0x1000 }, /* WFDMA_1 (PCIE0 MCU DMA1) */
{ 0x56000000, 0x404000, 0x1000 }, /* WFDMA_2 (Reserved) */
{ 0x57000000, 0x405000, 0x1000 }, /* WFDMA_3 (MCU wrap CR) */
{ 0x58000000, 0x406000, 0x1000 }, /* WFDMA_4 (PCIE1 MCU DMA0) */
{ 0x59000000, 0x407000, 0x1000 }, /* WFDMA_5 (PCIE1 MCU DMA1) */
{ 0x820c0000, 0x408000, 0x4000 }, /* WF_UMAC_TOP (PLE) */
{ 0x820c8000, 0x40c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */
{ 0x820cc000, 0x40e000, 0x2000 }, /* WF_UMAC_TOP (PP) */
{ 0x820e0000, 0x420000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */
{ 0x820e1000, 0x420400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */
{ 0x820e2000, 0x420800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */
{ 0x820e3000, 0x420c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */
{ 0x820e4000, 0x421000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */
{ 0x820e5000, 0x421400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */
{ 0x820ce000, 0x421c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */
{ 0x820e7000, 0x421e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */
{ 0x820cf000, 0x422000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */
{ 0x820e9000, 0x423400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */
{ 0x820ea000, 0x424000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */
{ 0x820eb000, 0x424200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */
{ 0x820ec000, 0x424600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */
{ 0x820ed000, 0x424800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */
{ 0x820ca000, 0x426000, 0x2000 }, /* WF_LMAC_TOP BN0 (WF_MUCOP) */
{ 0x820d0000, 0x430000, 0x10000}, /* WF_LMAC_TOP (WF_WTBLON) */
{ 0x00400000, 0x480000, 0x10000}, /* WF_MCU_SYSRAM */
{ 0x00410000, 0x490000, 0x10000}, /* WF_MCU_SYSRAM */
{ 0x820f0000, 0x4a0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */
{ 0x820f1000, 0x4a0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */
{ 0x820f2000, 0x4a0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */
{ 0x820f3000, 0x4a0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */
{ 0x820f4000, 0x4a1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */
{ 0x820f5000, 0x4a1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */
{ 0x820f7000, 0x4a1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */
{ 0x820f9000, 0x4a3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */
{ 0x820fa000, 0x4a4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */
{ 0x820fb000, 0x4a4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */
{ 0x820fc000, 0x4a4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */
{ 0x820fd000, 0x4a4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */
{ 0x820c4000, 0x4a8000, 0x1000 }, /* WF_LMAC_TOP (WF_UWTBL ) */
{ 0x820b0000, 0x4ae000, 0x1000 }, /* [APB2] WFSYS_ON */
{ 0x80020000, 0x4b0000, 0x10000}, /* WF_TOP_MISC_OFF */
{ 0x81020000, 0x4c0000, 0x10000}, /* WF_TOP_MISC_ON */
{ 0x89000000, 0x4d0000, 0x1000 }, /* WF_MCU_CFG_ON */
{ 0x89010000, 0x4d1000, 0x1000 }, /* WF_MCU_CIRQ */
{ 0x89020000, 0x4d2000, 0x1000 }, /* WF_MCU_GPT */
{ 0x89030000, 0x4d3000, 0x1000 }, /* WF_MCU_WDT */
{ 0x80010000, 0x4d4000, 0x1000 }, /* WF_AXIDMA */
{ 0x0, 0x0, 0x0 }, /* imply end of search */
};
static u32 mt7915_reg_map_l1(struct mt7915_dev *dev, u32 addr) static u32 mt7915_reg_map_l1(struct mt7915_dev *dev, u32 addr)
{ {
u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr); u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);
u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr); u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);
u32 l1_remap = is_mt7915(&dev->mt76) ? u32 l1_remap;
MT_HIF_REMAP_L1 : MT_HIF_REMAP_L1_MT7916;
if (is_mt7986(&dev->mt76))
return MT_CONN_INFRA_OFFSET(addr);
l1_remap = is_mt7915(&dev->mt76) ?
MT_HIF_REMAP_L1 : MT_HIF_REMAP_L1_MT7916;
dev->bus_ops->rmw(&dev->mt76, l1_remap, dev->bus_ops->rmw(&dev->mt76, l1_remap,
MT_HIF_REMAP_L1_MASK, MT_HIF_REMAP_L1_MASK,
...@@ -295,17 +376,19 @@ static u32 mt7915_reg_map_l2(struct mt7915_dev *dev, u32 addr) ...@@ -295,17 +376,19 @@ static u32 mt7915_reg_map_l2(struct mt7915_dev *dev, u32 addr)
/* use read to push write */ /* use read to push write */
dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2); dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2);
} else { } else {
u32 ofs = is_mt7986(&dev->mt76) ? 0x400000 : 0;
offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET_MT7916, addr); offset = FIELD_GET(MT_HIF_REMAP_L2_OFFSET_MT7916, addr);
base = FIELD_GET(MT_HIF_REMAP_L2_BASE_MT7916, addr); base = FIELD_GET(MT_HIF_REMAP_L2_BASE_MT7916, addr);
dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2_MT7916, dev->bus_ops->rmw(&dev->mt76, MT_HIF_REMAP_L2_MT7916 + ofs,
MT_HIF_REMAP_L2_MASK_MT7916, MT_HIF_REMAP_L2_MASK_MT7916,
FIELD_PREP(MT_HIF_REMAP_L2_MASK_MT7916, base)); FIELD_PREP(MT_HIF_REMAP_L2_MASK_MT7916, base));
/* use read to push write */ /* use read to push write */
dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2_MT7916); dev->bus_ops->rr(&dev->mt76, MT_HIF_REMAP_L2_MT7916 + ofs);
offset += MT_HIF_REMAP_BASE_L2_MT7916; offset += (MT_HIF_REMAP_BASE_L2_MT7916 + ofs);
} }
return offset; return offset;
...@@ -338,11 +421,20 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr) ...@@ -338,11 +421,20 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) || if ((addr >= MT_INFRA_BASE && addr < MT_WFSYS0_PHY_START) ||
(addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) || (addr >= MT_WFSYS0_PHY_START && addr < MT_WFSYS1_PHY_START) ||
(addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END) || (addr >= MT_WFSYS1_PHY_START && addr <= MT_WFSYS1_PHY_END))
(addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) || return mt7915_reg_map_l1(dev, addr);
(addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END))
if (dev_is_pci(dev->mt76.dev) &&
((addr >= MT_CBTOP1_PHY_START && addr <= MT_CBTOP1_PHY_END) ||
(addr >= MT_CBTOP2_PHY_START && addr <= MT_CBTOP2_PHY_END)))
return mt7915_reg_map_l1(dev, addr); return mt7915_reg_map_l1(dev, addr);
/* CONN_INFRA: covert to phyiscal addr and use layer 1 remap */
if (addr >= MT_INFRA_MCU_START && addr <= MT_INFRA_MCU_END) {
addr = addr - MT_INFRA_MCU_START + MT_INFRA_BASE;
return mt7915_reg_map_l1(dev, addr);
}
return mt7915_reg_map_l2(dev, addr); return mt7915_reg_map_l2(dev, addr);
} }
...@@ -393,6 +485,12 @@ static int mt7915_mmio_init(struct mt76_dev *mdev, ...@@ -393,6 +485,12 @@ static int mt7915_mmio_init(struct mt76_dev *mdev,
dev->reg.map = mt7916_reg_map; dev->reg.map = mt7916_reg_map;
dev->reg.map_size = ARRAY_SIZE(mt7916_reg_map); dev->reg.map_size = ARRAY_SIZE(mt7916_reg_map);
break; break;
case 0x7986:
dev->reg.reg_rev = mt7986_reg;
dev->reg.offs_rev = mt7916_offs;
dev->reg.map = mt7986_reg_map;
dev->reg.map_size = ARRAY_SIZE(mt7986_reg_map);
break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -585,13 +683,29 @@ static int __init mt7915_init(void) ...@@ -585,13 +683,29 @@ static int __init mt7915_init(void)
ret = pci_register_driver(&mt7915_pci_driver); ret = pci_register_driver(&mt7915_pci_driver);
if (ret) if (ret)
pci_unregister_driver(&mt7915_hif_driver); goto error_pci;
if (IS_ENABLED(CONFIG_MT7986_WMAC)) {
ret = platform_driver_register(&mt7986_wmac_driver);
if (ret)
goto error_wmac;
}
return 0;
error_wmac:
pci_unregister_driver(&mt7915_pci_driver);
error_pci:
pci_unregister_driver(&mt7915_hif_driver);
return ret; return ret;
} }
static void __exit mt7915_exit(void) static void __exit mt7915_exit(void)
{ {
if (IS_ENABLED(CONFIG_MT7986_WMAC))
platform_driver_unregister(&mt7986_wmac_driver);
pci_unregister_driver(&mt7915_pci_driver); pci_unregister_driver(&mt7915_pci_driver);
pci_unregister_driver(&mt7915_hif_driver); pci_unregister_driver(&mt7915_hif_driver);
} }
......
...@@ -35,9 +35,20 @@ ...@@ -35,9 +35,20 @@
#define MT7916_FIRMWARE_WM "mediatek/mt7916_wm.bin" #define MT7916_FIRMWARE_WM "mediatek/mt7916_wm.bin"
#define MT7916_ROM_PATCH "mediatek/mt7916_rom_patch.bin" #define MT7916_ROM_PATCH "mediatek/mt7916_rom_patch.bin"
#define MT7986_FIRMWARE_WA "mediatek/mt7986_wa.bin"
#define MT7986_FIRMWARE_WM "mediatek/mt7986_wm.bin"
#define MT7986_FIRMWARE_WM_MT7975 "mediatek/mt7986_wm_mt7975.bin"
#define MT7986_ROM_PATCH "mediatek/mt7986_rom_patch.bin"
#define MT7986_ROM_PATCH_MT7975 "mediatek/mt7986_rom_patch_mt7975.bin"
#define MT7915_EEPROM_DEFAULT "mediatek/mt7915_eeprom.bin" #define MT7915_EEPROM_DEFAULT "mediatek/mt7915_eeprom.bin"
#define MT7915_EEPROM_DEFAULT_DBDC "mediatek/mt7915_eeprom_dbdc.bin" #define MT7915_EEPROM_DEFAULT_DBDC "mediatek/mt7915_eeprom_dbdc.bin"
#define MT7916_EEPROM_DEFAULT "mediatek/mt7916_eeprom.bin" #define MT7916_EEPROM_DEFAULT "mediatek/mt7916_eeprom.bin"
#define MT7986_EEPROM_MT7975_DEFAULT "mediatek/mt7986_eeprom_mt7975.bin"
#define MT7986_EEPROM_MT7975_DUAL_DEFAULT "mediatek/mt7986_eeprom_mt7975_dual.bin"
#define MT7986_EEPROM_MT7976_DEFAULT "mediatek/mt7986_eeprom_mt7976.bin"
#define MT7986_EEPROM_MT7976_DEFAULT_DBDC "mediatek/mt7986_eeprom_mt7976_dbdc.bin"
#define MT7986_EEPROM_MT7976_DUAL_DEFAULT "mediatek/mt7986_eeprom_mt7976_dual.bin"
#define MT7915_EEPROM_SIZE 3584 #define MT7915_EEPROM_SIZE 3584
#define MT7916_EEPROM_SIZE 4096 #define MT7916_EEPROM_SIZE 4096
...@@ -49,6 +60,7 @@ ...@@ -49,6 +60,7 @@
#define MT7915_CFEND_RATE_11B 0x03 /* 11B LP, 11M */ #define MT7915_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
#define MT7915_THERMAL_THROTTLE_MAX 100 #define MT7915_THERMAL_THROTTLE_MAX 100
#define MT7915_CDEV_THROTTLE_MAX 99
#define MT7915_SKU_RATE_NUM 161 #define MT7915_SKU_RATE_NUM 161
...@@ -218,11 +230,13 @@ struct mt7915_phy { ...@@ -218,11 +230,13 @@ struct mt7915_phy {
struct ieee80211_vif *monitor_vif; struct ieee80211_vif *monitor_vif;
struct thermal_cooling_device *cdev; struct thermal_cooling_device *cdev;
u8 cdev_state;
u8 throttle_state; u8 throttle_state;
u32 throttle_temp[2]; /* 0: critical high, 1: maximum */ u32 throttle_temp[2]; /* 0: critical high, 1: maximum */
u32 rxfilter; u32 rxfilter;
u64 omac_mask; u64 omac_mask;
u8 band_idx;
u16 noise; u16 noise;
...@@ -273,6 +287,7 @@ struct mt7915_dev { ...@@ -273,6 +287,7 @@ struct mt7915_dev {
struct mt7915_phy *rdd2_phy; struct mt7915_phy *rdd2_phy;
u16 chainmask; u16 chainmask;
u16 chainshift;
u32 hif_idx; u32 hif_idx;
struct work_struct init_work; struct work_struct init_work;
...@@ -305,6 +320,10 @@ struct mt7915_dev { ...@@ -305,6 +320,10 @@ struct mt7915_dev {
u8 table_mask; u8 table_mask;
u8 n_agrt; u8 n_agrt;
} twt; } twt;
struct reset_control *rstc;
void __iomem *dcm;
void __iomem *sku;
}; };
enum { enum {
...@@ -377,11 +396,35 @@ mt7915_ext_phy(struct mt7915_dev *dev) ...@@ -377,11 +396,35 @@ mt7915_ext_phy(struct mt7915_dev *dev)
return phy->priv; return phy->priv;
} }
static inline u32 mt7915_check_adie(struct mt7915_dev *dev, bool sku)
{
u32 mask = sku ? MT_CONNINFRA_SKU_MASK : MT_ADIE_TYPE_MASK;
if (!is_mt7986(&dev->mt76))
return 0;
return mt76_rr(dev, MT_CONNINFRA_SKU_DEC_ADDR) & mask;
}
extern const struct ieee80211_ops mt7915_ops; extern const struct ieee80211_ops mt7915_ops;
extern const struct mt76_testmode_ops mt7915_testmode_ops; extern const struct mt76_testmode_ops mt7915_testmode_ops;
extern struct pci_driver mt7915_pci_driver; extern struct pci_driver mt7915_pci_driver;
extern struct pci_driver mt7915_hif_driver; extern struct pci_driver mt7915_hif_driver;
extern struct platform_driver mt7986_wmac_driver;
#ifdef CONFIG_MT7986_WMAC
int mt7986_wmac_enable(struct mt7915_dev *dev);
void mt7986_wmac_disable(struct mt7915_dev *dev);
#else
static inline int mt7986_wmac_enable(struct mt7915_dev *dev)
{
return 0;
}
static inline void mt7986_wmac_disable(struct mt7915_dev *dev)
{
}
#endif
struct mt7915_dev *mt7915_mmio_probe(struct device *pdev, struct mt7915_dev *mt7915_mmio_probe(struct device *pdev,
void __iomem *mem_base, u32 device_id); void __iomem *mem_base, u32 device_id);
irqreturn_t mt7915_irq_handler(int irq, void *dev_instance); irqreturn_t mt7915_irq_handler(int irq, void *dev_instance);
......
This diff is collapsed.
...@@ -198,7 +198,6 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode) ...@@ -198,7 +198,6 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
u8 slot_time = 9, sifs = TM_DEFAULT_SIFS; u8 slot_time = 9, sifs = TM_DEFAULT_SIFS;
u8 aifsn = TM_MIN_AIFSN; u8 aifsn = TM_MIN_AIFSN;
u32 i2t_time, tr2t_time, txv_time; u32 i2t_time, tr2t_time, txv_time;
bool ext_phy = phy != &dev->phy;
u16 cw = 0; u16 cw = 0;
if (ipg < sig_ext + slot_time + sifs) if (ipg < sig_ext + slot_time + sifs)
...@@ -228,22 +227,18 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode) ...@@ -228,22 +227,18 @@ mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
ipg -= aifsn * slot_time; ipg -= aifsn * slot_time;
if (ipg > TM_DEFAULT_SIFS) { if (ipg > TM_DEFAULT_SIFS)
if (ipg < TM_MAX_SIFS) sifs = min_t(u32, ipg, TM_MAX_SIFS);
sifs = ipg;
else
sifs = TM_MAX_SIFS;
}
} }
done: done:
txv_time = mt76_get_field(dev, MT_TMAC_ATCR(ext_phy), txv_time = mt76_get_field(dev, MT_TMAC_ATCR(phy->band_idx),
MT_TMAC_ATCR_TXV_TOUT); MT_TMAC_ATCR_TXV_TOUT);
txv_time *= 50; /* normal clock time */ txv_time *= 50; /* normal clock time */
i2t_time = (slot_time * 1000 - txv_time - BBP_PROC_TIME) / 50; i2t_time = (slot_time * 1000 - txv_time - BBP_PROC_TIME) / 50;
tr2t_time = (sifs * 1000 - txv_time - BBP_PROC_TIME) / 50; tr2t_time = (sifs * 1000 - txv_time - BBP_PROC_TIME) / 50;
mt76_set(dev, MT_TMAC_TRCR0(ext_phy), mt76_set(dev, MT_TMAC_TRCR0(phy->band_idx),
FIELD_PREP(MT_TMAC_TRCR0_TR2T_CHK, tr2t_time) | FIELD_PREP(MT_TMAC_TRCR0_TR2T_CHK, tr2t_time) |
FIELD_PREP(MT_TMAC_TRCR0_I2T_CHK, i2t_time)); FIELD_PREP(MT_TMAC_TRCR0_I2T_CHK, i2t_time));
...@@ -337,7 +332,6 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy) ...@@ -337,7 +332,6 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
{ {
int n_regs = ARRAY_SIZE(reg_backup_list); int n_regs = ARRAY_SIZE(reg_backup_list);
struct mt7915_dev *dev = phy->dev; struct mt7915_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
u32 *b = phy->test.reg_backup; u32 *b = phy->test.reg_backup;
int i; int i;
...@@ -361,7 +355,7 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy) ...@@ -361,7 +355,7 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
if (phy->mt76->test.state == MT76_TM_STATE_OFF) { if (phy->mt76->test.state == MT76_TM_STATE_OFF) {
for (i = 0; i < n_regs; i++) for (i = 0; i < n_regs; i++)
mt76_wr(dev, reg_backup_list[i].band[ext_phy], b[i]); mt76_wr(dev, reg_backup_list[i].band[phy->band_idx], b[i]);
return; return;
} }
...@@ -372,33 +366,33 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy) ...@@ -372,33 +366,33 @@ mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
phy->test.reg_backup = b; phy->test.reg_backup = b;
for (i = 0; i < n_regs; i++) for (i = 0; i < n_regs; i++)
b[i] = mt76_rr(dev, reg_backup_list[i].band[ext_phy]); b[i] = mt76_rr(dev, reg_backup_list[i].band[phy->band_idx]);
} }
mt76_clear(dev, MT_AGG_PCR0(ext_phy, 0), MT_AGG_PCR0_MM_PROT | mt76_clear(dev, MT_AGG_PCR0(phy->band_idx, 0), MT_AGG_PCR0_MM_PROT |
MT_AGG_PCR0_GF_PROT | MT_AGG_PCR0_ERP_PROT | MT_AGG_PCR0_GF_PROT | MT_AGG_PCR0_ERP_PROT |
MT_AGG_PCR0_VHT_PROT | MT_AGG_PCR0_BW20_PROT | MT_AGG_PCR0_VHT_PROT | MT_AGG_PCR0_BW20_PROT |
MT_AGG_PCR0_BW40_PROT | MT_AGG_PCR0_BW80_PROT); MT_AGG_PCR0_BW40_PROT | MT_AGG_PCR0_BW80_PROT);
mt76_set(dev, MT_AGG_PCR0(ext_phy, 0), MT_AGG_PCR0_PTA_WIN_DIS); mt76_set(dev, MT_AGG_PCR0(phy->band_idx, 0), MT_AGG_PCR0_PTA_WIN_DIS);
mt76_wr(dev, MT_AGG_PCR0(ext_phy, 1), MT_AGG_PCR1_RTS0_NUM_THRES | mt76_wr(dev, MT_AGG_PCR0(phy->band_idx, 1), MT_AGG_PCR1_RTS0_NUM_THRES |
MT_AGG_PCR1_RTS0_LEN_THRES); MT_AGG_PCR1_RTS0_LEN_THRES);
mt76_clear(dev, MT_AGG_MRCR(ext_phy), MT_AGG_MRCR_BAR_CNT_LIMIT | mt76_clear(dev, MT_AGG_MRCR(phy->band_idx), MT_AGG_MRCR_BAR_CNT_LIMIT |
MT_AGG_MRCR_LAST_RTS_CTS_RN | MT_AGG_MRCR_RTS_FAIL_LIMIT | MT_AGG_MRCR_LAST_RTS_CTS_RN | MT_AGG_MRCR_RTS_FAIL_LIMIT |
MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT); MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT);
mt76_rmw(dev, MT_AGG_MRCR(ext_phy), MT_AGG_MRCR_RTS_FAIL_LIMIT | mt76_rmw(dev, MT_AGG_MRCR(phy->band_idx), MT_AGG_MRCR_RTS_FAIL_LIMIT |
MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT,
FIELD_PREP(MT_AGG_MRCR_RTS_FAIL_LIMIT, 1) | FIELD_PREP(MT_AGG_MRCR_RTS_FAIL_LIMIT, 1) |
FIELD_PREP(MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, 1)); FIELD_PREP(MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT, 1));
mt76_wr(dev, MT_TMAC_TFCR0(ext_phy), 0); mt76_wr(dev, MT_TMAC_TFCR0(phy->band_idx), 0);
mt76_clear(dev, MT_TMAC_TCR0(ext_phy), MT_TMAC_TCR0_TBTT_STOP_CTRL); mt76_clear(dev, MT_TMAC_TCR0(phy->band_idx), MT_TMAC_TCR0_TBTT_STOP_CTRL);
/* config rx filter for testmode rx */ /* config rx filter for testmode rx */
mt76_wr(dev, MT_WF_RFCR(ext_phy), 0xcf70a); mt76_wr(dev, MT_WF_RFCR(phy->band_idx), 0xcf70a);
mt76_wr(dev, MT_WF_RFCR1(ext_phy), 0); mt76_wr(dev, MT_WF_RFCR1(phy->band_idx), 0);
} }
static void static void
...@@ -456,7 +450,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en) ...@@ -456,7 +450,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
u8 tx_ant = td->tx_antenna_mask; u8 tx_ant = td->tx_antenna_mask;
if (phy != &dev->phy) if (phy != &dev->phy)
tx_ant >>= 2; tx_ant >>= dev->chainshift;
phy->test.spe_idx = spe_idx_map[tx_ant]; phy->test.spe_idx = spe_idx_map[tx_ant];
} }
} }
...@@ -724,7 +718,6 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) ...@@ -724,7 +718,6 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
{ {
struct mt7915_phy *phy = mphy->priv; struct mt7915_phy *phy = mphy->priv;
struct mt7915_dev *dev = phy->dev; struct mt7915_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy;
enum mt76_rxq_id q; enum mt76_rxq_id q;
void *rx, *rssi; void *rx, *rssi;
u16 fcs_err; u16 fcs_err;
...@@ -773,11 +766,11 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) ...@@ -773,11 +766,11 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
nla_nest_end(msg, rx); nla_nest_end(msg, rx);
cnt = mt76_rr(dev, MT_MIB_SDR3(ext_phy)); cnt = mt76_rr(dev, MT_MIB_SDR3(phy->band_idx));
fcs_err = is_mt7915(&dev->mt76) ? FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK, cnt) : fcs_err = is_mt7915(&dev->mt76) ? FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK, cnt) :
FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK_MT7916, cnt); FIELD_GET(MT_MIB_SDR3_FCS_ERR_MASK_MT7916, cnt);
q = ext_phy ? MT_RXQ_EXT : MT_RXQ_MAIN; q = phy->band_idx ? MT_RXQ_EXT : MT_RXQ_MAIN;
mphy->test.rx_stats.packets[q] += fcs_err; mphy->test.rx_stats.packets[q] += fcs_err;
mphy->test.rx_stats.fcs_error[q] += fcs_err; mphy->test.rx_stats.fcs_error[q] += fcs_err;
......
...@@ -407,7 +407,7 @@ static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) ...@@ -407,7 +407,7 @@ static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
struct ieee80211_hdr hdr; struct ieee80211_hdr hdr;
__le32 qos_ctrl, ht_ctrl; u16 frame_control;
if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) != if (FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, le32_to_cpu(rxd[3])) !=
MT_RXD3_NORMAL_U2M) MT_RXD3_NORMAL_U2M)
...@@ -423,16 +423,15 @@ static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) ...@@ -423,16 +423,15 @@ static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
/* store the info from RXD and ethhdr to avoid being overridden */ /* store the info from RXD and ethhdr to avoid being overridden */
hdr.frame_control = FIELD_GET(MT_RXD6_FRAME_CONTROL, rxd[6]); frame_control = le32_get_bits(rxd[6], MT_RXD6_FRAME_CONTROL);
hdr.seq_ctrl = FIELD_GET(MT_RXD8_SEQ_CTRL, rxd[8]); hdr.frame_control = cpu_to_le16(frame_control);
qos_ctrl = FIELD_GET(MT_RXD8_QOS_CTL, rxd[8]); hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_SEQ_CTRL));
ht_ctrl = FIELD_GET(MT_RXD9_HT_CONTROL, rxd[9]);
hdr.duration_id = 0; hdr.duration_id = 0;
ether_addr_copy(hdr.addr1, vif->addr); ether_addr_copy(hdr.addr1, vif->addr);
ether_addr_copy(hdr.addr2, sta->addr); ether_addr_copy(hdr.addr2, sta->addr);
switch (le16_to_cpu(hdr.frame_control) & switch (frame_control & (IEEE80211_FCTL_TODS |
(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { IEEE80211_FCTL_FROMDS)) {
case 0: case 0:
ether_addr_copy(hdr.addr3, vif->bss_conf.bssid); ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
break; break;
...@@ -454,15 +453,22 @@ static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) ...@@ -454,15 +453,22 @@ static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) || if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) ||
eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX)) eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX))
ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header); ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
else if (eth_hdr->h_proto >= cpu_to_be16(ETH_P_802_3_MIN)) else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN)
ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header); ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
else else
skb_pull(skb, 2); skb_pull(skb, 2);
if (ieee80211_has_order(hdr.frame_control)) if (ieee80211_has_order(hdr.frame_control))
memcpy(skb_push(skb, 2), &ht_ctrl, 2); memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[9],
if (ieee80211_is_data_qos(hdr.frame_control)) IEEE80211_HT_CTL_LEN);
memcpy(skb_push(skb, 2), &qos_ctrl, 2); if (ieee80211_is_data_qos(hdr.frame_control)) {
__le16 qos_ctrl;
qos_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_QOS_CTL));
memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl,
IEEE80211_QOS_CTL_LEN);
}
if (ieee80211_has_a4(hdr.frame_control)) if (ieee80211_has_a4(hdr.frame_control))
memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr)); memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
else else
...@@ -664,9 +670,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) ...@@ -664,9 +670,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
status->chain_signal[i]); status->chain_signal[i]);
} }
if (status->signal == -128)
status->flag |= RX_FLAG_NO_SIGNAL_VAL;
stbc = FIELD_GET(MT_PRXV_STBC, v0); stbc = FIELD_GET(MT_PRXV_STBC, v0);
gi = FIELD_GET(MT_PRXV_SGI, v0); gi = FIELD_GET(MT_PRXV_SGI, v0);
cck = false; cck = false;
...@@ -910,11 +913,18 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi, ...@@ -910,11 +913,18 @@ mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi,
val = MT_TXD3_SN_VALID | val = MT_TXD3_SN_VALID |
FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno)); FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
txwi[3] |= cpu_to_le32(val); txwi[3] |= cpu_to_le32(val);
txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU);
} }
val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | if (mt76_is_mmio(&dev->mt76)) {
FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
txwi[7] |= cpu_to_le32(val); FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
txwi[7] |= cpu_to_le32(val);
} else {
val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) |
FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype);
txwi[8] |= cpu_to_le32(val);
}
} }
void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
......
...@@ -284,6 +284,9 @@ enum tx_mcu_port_q_idx { ...@@ -284,6 +284,9 @@ enum tx_mcu_port_q_idx {
#define MT_TXD7_HW_AMSDU BIT(10) #define MT_TXD7_HW_AMSDU BIT(10)
#define MT_TXD7_TX_TIME GENMASK(9, 0) #define MT_TXD7_TX_TIME GENMASK(9, 0)
#define MT_TXD8_L_TYPE GENMASK(5, 4)
#define MT_TXD8_L_SUB_TYPE GENMASK(3, 0)
#define MT_TX_RATE_STBC BIT(13) #define MT_TX_RATE_STBC BIT(13)
#define MT_TX_RATE_NSS GENMASK(12, 10) #define MT_TX_RATE_NSS GENMASK(12, 10)
#define MT_TX_RATE_MODE GENMASK(9, 6) #define MT_TX_RATE_MODE GENMASK(9, 6)
......
...@@ -863,10 +863,12 @@ int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd) ...@@ -863,10 +863,12 @@ int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
else else
req.channel_band = chandef->chan->band; req.channel_band = chandef->chan->band;
if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) if (cmd == MCU_EXT_CMD(SET_RX_PATH))
req.switch_reason = CH_SWITCH_NORMAL;
else if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD; req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
else if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) && else if (!cfg80211_reg_can_beacon(dev->mt76.hw->wiphy, chandef,
chandef->chan->dfs_state != NL80211_DFS_AVAILABLE) NL80211_IFTYPE_AP))
req.switch_reason = CH_SWITCH_DFS; req.switch_reason = CH_SWITCH_DFS;
else else
req.switch_reason = CH_SWITCH_NORMAL; req.switch_reason = CH_SWITCH_NORMAL;
......
...@@ -409,7 +409,6 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -409,7 +409,6 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct mt76_dev *dev = phy->dev; struct mt76_dev *dev = phy->dev;
struct mt76_testmode_data *td = &phy->test; struct mt76_testmode_data *td = &phy->test;
struct nlattr *tb[NUM_MT76_TM_ATTRS]; struct nlattr *tb[NUM_MT76_TM_ATTRS];
bool ext_phy = phy != &dev->phy;
u32 state; u32 state;
int err; int err;
int i; int i;
...@@ -447,8 +446,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -447,8 +446,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_LDPC], &td->tx_rate_ldpc, 0, 1) || mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_LDPC], &td->tx_rate_ldpc, 0, 1) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_STBC], &td->tx_rate_stbc, 0, 1) || mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_STBC], &td->tx_rate_stbc, 0, 1) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_LTF], &td->tx_ltf, 0, 2) || mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_LTF], &td->tx_ltf, 0, 2) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask, mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA],
1 << (ext_phy * 2), phy->antenna_mask << (ext_phy * 2)) || &td->tx_antenna_mask, 0, 0xff) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_SPE_IDX], &td->tx_spe_idx, 0, 27) || mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_SPE_IDX], &td->tx_spe_idx, 0, 27) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_DUTY_CYCLE], mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_DUTY_CYCLE],
&td->tx_duty_cycle, 0, 99) || &td->tx_duty_cycle, 0, 99) ||
......
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