mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-05 13:29:17 -04:00
mt76: move mt76_connac2_mcu_fill_message in mt76_connac module
Move mt76_connac2_mcu_fill_message routine in shared module in order to reuse it for mt7921 and mt7915e drivers. This is a preliminary patch to add mt7990 driver support. Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
committed by
Felix Fietkau
parent
fc6ee71a2a
commit
d2f5c8ed9f
@@ -201,9 +201,6 @@ struct mt7615_mcu_rdd_report {
|
||||
} hw_pulse[32];
|
||||
};
|
||||
|
||||
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
|
||||
#define MCU_PKT_ID 0xa0
|
||||
|
||||
enum {
|
||||
MCU_ATE_SET_FREQ_OFFSET = 0xa,
|
||||
MCU_ATE_SET_TX_POWER_CONTROL = 0x15,
|
||||
|
||||
@@ -307,4 +307,17 @@ enum {
|
||||
#define MT_CT_INFO_HSR2_TX BIT(4)
|
||||
#define MT_CT_INFO_FROM_HOST BIT(7)
|
||||
|
||||
enum tx_mcu_port_q_idx {
|
||||
MT_TX_MCU_PORT_RX_Q0 = 0x20,
|
||||
MT_TX_MCU_PORT_RX_Q1,
|
||||
MT_TX_MCU_PORT_RX_Q2,
|
||||
MT_TX_MCU_PORT_RX_Q3,
|
||||
MT_TX_MCU_PORT_RX_FWDL = 0x3e
|
||||
};
|
||||
|
||||
enum tx_port_idx {
|
||||
MT_TX_PORT_IDX_LMAC,
|
||||
MT_TX_PORT_IDX_MCU
|
||||
};
|
||||
|
||||
#endif /* __MT76_CONNAC2_MAC_H */
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#include <linux/firmware.h>
|
||||
#include "mt76_connac2_mac.h"
|
||||
#include "mt76_connac_mcu.h"
|
||||
|
||||
int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
|
||||
@@ -3034,5 +3035,81 @@ int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac2_load_patch);
|
||||
|
||||
int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
int cmd, int *wait_seq)
|
||||
{
|
||||
int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
|
||||
struct mt76_connac2_mcu_uni_txd *uni_txd;
|
||||
struct mt76_connac2_mcu_txd *mcu_txd;
|
||||
__le32 *txd;
|
||||
u32 val;
|
||||
u8 seq;
|
||||
|
||||
/* TODO: make dynamic based on msg type */
|
||||
dev->mcu.timeout = 20 * HZ;
|
||||
|
||||
seq = ++dev->mcu.msg_seq & 0xf;
|
||||
if (!seq)
|
||||
seq = ++dev->mcu.msg_seq & 0xf;
|
||||
|
||||
if (cmd == MCU_CMD(FW_SCATTER))
|
||||
goto exit;
|
||||
|
||||
txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);
|
||||
txd = (__le32 *)skb_push(skb, txd_len);
|
||||
|
||||
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
|
||||
FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |
|
||||
FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);
|
||||
txd[0] = cpu_to_le32(val);
|
||||
|
||||
val = MT_TXD1_LONG_FORMAT |
|
||||
FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);
|
||||
txd[1] = cpu_to_le32(val);
|
||||
|
||||
if (cmd & __MCU_CMD_FIELD_UNI) {
|
||||
uni_txd = (struct mt76_connac2_mcu_uni_txd *)txd;
|
||||
uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));
|
||||
uni_txd->option = MCU_CMD_UNI_EXT_ACK;
|
||||
uni_txd->cid = cpu_to_le16(mcu_cmd);
|
||||
uni_txd->s2d_index = MCU_S2D_H2N;
|
||||
uni_txd->pkt_type = MCU_PKT_ID;
|
||||
uni_txd->seq = seq;
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mcu_txd = (struct mt76_connac2_mcu_txd *)txd;
|
||||
mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));
|
||||
mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,
|
||||
MT_TX_MCU_PORT_RX_Q0));
|
||||
mcu_txd->pkt_type = MCU_PKT_ID;
|
||||
mcu_txd->seq = seq;
|
||||
mcu_txd->cid = mcu_cmd;
|
||||
mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
|
||||
|
||||
if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) {
|
||||
if (cmd & __MCU_CMD_FIELD_QUERY)
|
||||
mcu_txd->set_query = MCU_Q_QUERY;
|
||||
else
|
||||
mcu_txd->set_query = MCU_Q_SET;
|
||||
mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid;
|
||||
} else {
|
||||
mcu_txd->set_query = MCU_Q_NA;
|
||||
}
|
||||
|
||||
if (cmd & __MCU_CMD_FIELD_WA)
|
||||
mcu_txd->s2d_index = MCU_S2D_H2C;
|
||||
else
|
||||
mcu_txd->s2d_index = MCU_S2D_H2N;
|
||||
|
||||
exit:
|
||||
if (wait_seq)
|
||||
*wait_seq = seq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac2_mcu_fill_message);
|
||||
|
||||
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
#define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK GENMASK(15, 0)
|
||||
#define PATCH_SEC_ENC_AES_KEY_MASK GENMASK(7, 0)
|
||||
|
||||
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
|
||||
#define MCU_PKT_ID 0xa0
|
||||
|
||||
struct mt76_connac2_mcu_txd {
|
||||
__le32 txd[8];
|
||||
|
||||
@@ -1804,4 +1807,6 @@ int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index,
|
||||
int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
|
||||
const char *fw_wa);
|
||||
int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name);
|
||||
int mt76_connac2_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
|
||||
int cmd, int *wait_seq);
|
||||
#endif /* __MT76_CONNAC_MCU_H */
|
||||
|
||||
@@ -29,18 +29,6 @@ enum rx_pkt_type {
|
||||
PKT_TYPE_TXRX_NOTIFY_V0 = 0x18,
|
||||
};
|
||||
|
||||
enum tx_port_idx {
|
||||
MT_TX_PORT_IDX_LMAC,
|
||||
MT_TX_PORT_IDX_MCU
|
||||
};
|
||||
|
||||
enum tx_mcu_port_q_idx {
|
||||
MT_TX_MCU_PORT_RX_Q0 = 0x20,
|
||||
MT_TX_MCU_PORT_RX_Q1,
|
||||
MT_TX_MCU_PORT_RX_Q2,
|
||||
MT_TX_MCU_PORT_RX_Q3,
|
||||
MT_TX_MCU_PORT_RX_FWDL = 0x3e
|
||||
};
|
||||
#define MT_TX_FREE_VER GENMASK(18, 16)
|
||||
#define MT_TX_FREE_MSDU_CNT GENMASK(9, 0)
|
||||
#define MT_TX_FREE_MSDU_CNT_V0 GENMASK(6, 0)
|
||||
|
||||
@@ -181,69 +181,20 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
|
||||
int cmd, int *wait_seq)
|
||||
{
|
||||
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
|
||||
struct mt76_connac2_mcu_txd *mcu_txd;
|
||||
enum mt76_mcuq_id qid;
|
||||
__le32 *txd;
|
||||
u32 val;
|
||||
u8 seq;
|
||||
int ret;
|
||||
|
||||
/* TODO: make dynamic based on msg type */
|
||||
mdev->mcu.timeout = 20 * HZ;
|
||||
ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, wait_seq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
seq = ++dev->mt76.mcu.msg_seq & 0xf;
|
||||
if (!seq)
|
||||
seq = ++dev->mt76.mcu.msg_seq & 0xf;
|
||||
|
||||
if (cmd == MCU_CMD(FW_SCATTER)) {
|
||||
if (cmd == MCU_CMD(FW_SCATTER))
|
||||
qid = MT_MCUQ_FWDL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mcu_txd = (struct mt76_connac2_mcu_txd *)skb_push(skb, sizeof(*mcu_txd));
|
||||
if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
|
||||
else if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
|
||||
qid = MT_MCUQ_WA;
|
||||
else
|
||||
qid = MT_MCUQ_WM;
|
||||
|
||||
txd = mcu_txd->txd;
|
||||
|
||||
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
|
||||
FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |
|
||||
FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);
|
||||
txd[0] = cpu_to_le32(val);
|
||||
|
||||
val = MT_TXD1_LONG_FORMAT |
|
||||
FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);
|
||||
txd[1] = cpu_to_le32(val);
|
||||
|
||||
mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));
|
||||
mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,
|
||||
MT_TX_MCU_PORT_RX_Q0));
|
||||
mcu_txd->pkt_type = MCU_PKT_ID;
|
||||
mcu_txd->seq = seq;
|
||||
|
||||
mcu_txd->cid = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
|
||||
mcu_txd->set_query = MCU_Q_NA;
|
||||
mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
|
||||
if (mcu_txd->ext_cid) {
|
||||
mcu_txd->ext_cid_ack = 1;
|
||||
|
||||
/* do not use Q_SET for efuse */
|
||||
if (cmd & __MCU_CMD_FIELD_QUERY)
|
||||
mcu_txd->set_query = MCU_Q_QUERY;
|
||||
else
|
||||
mcu_txd->set_query = MCU_Q_SET;
|
||||
}
|
||||
|
||||
if (cmd & __MCU_CMD_FIELD_WA)
|
||||
mcu_txd->s2d_index = MCU_S2D_H2C;
|
||||
else
|
||||
mcu_txd->s2d_index = MCU_S2D_H2N;
|
||||
|
||||
exit:
|
||||
if (wait_seq)
|
||||
*wait_seq = seq;
|
||||
|
||||
return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -233,9 +233,6 @@ struct mt7915_mcu_muru_stats {
|
||||
#define WMM_TXOP_SET BIT(3)
|
||||
#define WMM_PARAM_SET GENMASK(3, 0)
|
||||
|
||||
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
|
||||
#define MCU_PKT_ID 0xa0
|
||||
|
||||
enum {
|
||||
MCU_FW_LOG_WM,
|
||||
MCU_FW_LOG_WA,
|
||||
|
||||
@@ -29,19 +29,6 @@ enum rx_pkt_type {
|
||||
PKT_TYPE_NORMAL_MCU,
|
||||
};
|
||||
|
||||
enum tx_port_idx {
|
||||
MT_TX_PORT_IDX_LMAC,
|
||||
MT_TX_PORT_IDX_MCU
|
||||
};
|
||||
|
||||
enum tx_mcu_port_q_idx {
|
||||
MT_TX_MCU_PORT_RX_Q0 = 0x20,
|
||||
MT_TX_MCU_PORT_RX_Q1,
|
||||
MT_TX_MCU_PORT_RX_Q2,
|
||||
MT_TX_MCU_PORT_RX_Q3,
|
||||
MT_TX_MCU_PORT_RX_FWDL = 0x3e
|
||||
};
|
||||
|
||||
#define MT_TX_FREE_MSDU_CNT GENMASK(9, 0)
|
||||
#define MT_TX_FREE_WLAN_ID GENMASK(23, 14)
|
||||
#define MT_TX_FREE_LATENCY GENMASK(12, 0)
|
||||
|
||||
@@ -84,83 +84,6 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7921_mcu_parse_response);
|
||||
|
||||
int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
|
||||
int cmd, int *wait_seq)
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
|
||||
struct mt76_connac2_mcu_uni_txd *uni_txd;
|
||||
struct mt76_connac2_mcu_txd *mcu_txd;
|
||||
__le32 *txd;
|
||||
u32 val;
|
||||
u8 seq;
|
||||
|
||||
if (cmd == MCU_UNI_CMD(HIF_CTRL) ||
|
||||
cmd == MCU_UNI_CMD(SUSPEND) ||
|
||||
cmd == MCU_UNI_CMD(OFFLOAD))
|
||||
mdev->mcu.timeout = HZ;
|
||||
else
|
||||
mdev->mcu.timeout = 3 * HZ;
|
||||
|
||||
seq = ++dev->mt76.mcu.msg_seq & 0xf;
|
||||
if (!seq)
|
||||
seq = ++dev->mt76.mcu.msg_seq & 0xf;
|
||||
|
||||
if (cmd == MCU_CMD(FW_SCATTER))
|
||||
goto exit;
|
||||
|
||||
txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);
|
||||
txd = (__le32 *)skb_push(skb, txd_len);
|
||||
|
||||
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
|
||||
FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |
|
||||
FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);
|
||||
txd[0] = cpu_to_le32(val);
|
||||
|
||||
val = MT_TXD1_LONG_FORMAT |
|
||||
FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);
|
||||
txd[1] = cpu_to_le32(val);
|
||||
|
||||
if (cmd & __MCU_CMD_FIELD_UNI) {
|
||||
uni_txd = (struct mt76_connac2_mcu_uni_txd *)txd;
|
||||
uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));
|
||||
uni_txd->option = MCU_CMD_UNI_EXT_ACK;
|
||||
uni_txd->cid = cpu_to_le16(mcu_cmd);
|
||||
uni_txd->s2d_index = MCU_S2D_H2N;
|
||||
uni_txd->pkt_type = MCU_PKT_ID;
|
||||
uni_txd->seq = seq;
|
||||
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mcu_txd = (struct mt76_connac2_mcu_txd *)txd;
|
||||
mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));
|
||||
mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,
|
||||
MT_TX_MCU_PORT_RX_Q0));
|
||||
mcu_txd->pkt_type = MCU_PKT_ID;
|
||||
mcu_txd->seq = seq;
|
||||
mcu_txd->cid = mcu_cmd;
|
||||
mcu_txd->s2d_index = MCU_S2D_H2N;
|
||||
mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
|
||||
|
||||
if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) {
|
||||
if (cmd & __MCU_CMD_FIELD_QUERY)
|
||||
mcu_txd->set_query = MCU_Q_QUERY;
|
||||
else
|
||||
mcu_txd->set_query = MCU_Q_SET;
|
||||
mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid;
|
||||
} else {
|
||||
mcu_txd->set_query = MCU_Q_NA;
|
||||
}
|
||||
|
||||
exit:
|
||||
if (wait_seq)
|
||||
*wait_seq = seq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7921_mcu_fill_message);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int
|
||||
|
||||
@@ -50,9 +50,6 @@ struct mt7921_mcu_eeprom_info {
|
||||
#define MT_RA_RATE_DCM_EN BIT(4)
|
||||
#define MT_RA_RATE_BW GENMASK(14, 13)
|
||||
|
||||
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
|
||||
#define MCU_PKT_ID 0xa0
|
||||
|
||||
struct mt7921_mcu_uni_event {
|
||||
u8 cid;
|
||||
u8 pad[3];
|
||||
|
||||
@@ -419,8 +419,6 @@ int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
|
||||
struct netlink_callback *cb, void *data, int len);
|
||||
void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi);
|
||||
void mt7921_mac_sta_poll(struct mt7921_dev *dev);
|
||||
int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb,
|
||||
int cmd, int *wait_seq);
|
||||
int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
|
||||
struct sk_buff *skb, int seq);
|
||||
|
||||
|
||||
@@ -26,10 +26,17 @@ mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
|
||||
enum mt76_mcuq_id txq = MT_MCUQ_WM;
|
||||
int ret;
|
||||
|
||||
ret = mt7921_mcu_fill_message(mdev, skb, cmd, seq);
|
||||
ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (cmd == MCU_UNI_CMD(HIF_CTRL) ||
|
||||
cmd == MCU_UNI_CMD(SUSPEND) ||
|
||||
cmd == MCU_UNI_CMD(OFFLOAD))
|
||||
mdev->mcu.timeout = HZ;
|
||||
else
|
||||
mdev->mcu.timeout = 3 * HZ;
|
||||
|
||||
if (cmd == MCU_CMD(FW_SCATTER))
|
||||
txq = MT_MCUQ_FWDL;
|
||||
|
||||
|
||||
@@ -29,10 +29,17 @@ mt7921s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
|
||||
if (dev->fw_assert)
|
||||
return -EBUSY;
|
||||
|
||||
ret = mt7921_mcu_fill_message(mdev, skb, cmd, seq);
|
||||
ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (cmd == MCU_UNI_CMD(HIF_CTRL) ||
|
||||
cmd == MCU_UNI_CMD(SUSPEND) ||
|
||||
cmd == MCU_UNI_CMD(OFFLOAD))
|
||||
mdev->mcu.timeout = HZ;
|
||||
else
|
||||
mdev->mcu.timeout = 3 * HZ;
|
||||
|
||||
if (cmd == MCU_CMD(FW_SCATTER))
|
||||
type = MT7921_SDIO_FWDL;
|
||||
|
||||
|
||||
@@ -102,10 +102,17 @@ mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
|
||||
u32 pad, ep;
|
||||
int ret;
|
||||
|
||||
ret = mt7921_mcu_fill_message(mdev, skb, cmd, seq);
|
||||
ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (cmd == MCU_UNI_CMD(HIF_CTRL) ||
|
||||
cmd == MCU_UNI_CMD(SUSPEND) ||
|
||||
cmd == MCU_UNI_CMD(OFFLOAD))
|
||||
mdev->mcu.timeout = HZ;
|
||||
else
|
||||
mdev->mcu.timeout = 3 * HZ;
|
||||
|
||||
if (cmd != MCU_CMD(FW_SCATTER))
|
||||
ep = MT_EP_OUT_INBAND_CMD;
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user