Introduce mcu uni command type. Uni commands rely on a stripped verions of mt7615_mcu_txd data strutture. Split mt7615_mcu_txd_common and mt7615_mcu_txd. Uni commands will be use by mt7663e driver Co-developed-by: Sean Wang <sean.wang@xxxxxxxxxxxx> Signed-off-by: Sean Wang <sean.wang@xxxxxxxxxxxx> Signed-off-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> --- .../net/wireless/mediatek/mt76/mt7615/mcu.c | 27 ++++++--- .../net/wireless/mediatek/mt76/mt7615/mcu.h | 60 ++++++++++++++++++- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index e73cd3cb014a..372ffc6322c9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -52,7 +52,8 @@ struct mt7615_fw_trailer { void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb, int cmd, int *wait_seq) { - int mcu_cmd = cmd & MCU_CMD_MASK; + int txd_len, mcu_cmd = cmd & MCU_CMD_MASK; + struct mt7615_uni_txd *uni_txd; struct mt7615_mcu_txd *mcu_txd; u8 seq, q_idx, pkt_fmt; __le32 *txd; @@ -61,8 +62,11 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb, seq = ++dev->mt76.mcu.msg_seq & 0xf; if (!seq) seq = ++dev->mt76.mcu.msg_seq & 0xf; + if (wait_seq) + *wait_seq = seq; - mcu_txd = (struct mt7615_mcu_txd *)skb_push(skb, sizeof(*mcu_txd)); + txd_len = cmd & MCU_UNI_PREFIX ? sizeof(*uni_txd) : sizeof(*mcu_txd); + txd = (__le32 *)skb_push(skb, txd_len); if (cmd != MCU_CMD_FW_SCATTER) { q_idx = MT_TX_MCU_PORT_RX_Q0; @@ -71,7 +75,6 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb, q_idx = MT_TX_MCU_PORT_RX_FWDL; pkt_fmt = MT_TX_TYPE_FW; } - txd = mcu_txd->txd; val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) | FIELD_PREP(MT_TXD0_P_IDX, MT_TX_PORT_IDX_MCU) | @@ -83,8 +86,22 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb, FIELD_PREP(MT_TXD1_PKT_FMT, pkt_fmt); txd[1] = cpu_to_le32(val); + if (cmd & MCU_UNI_PREFIX) { + uni_txd = (struct mt7615_uni_txd *)txd; + uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd)); + uni_txd->option = MCU_CMD_UNI_EXT_ACK; + uni_txd->s2d_index = MCU_S2D_H2N; + uni_txd->pkt_type = MCU_PKT_ID; + uni_txd->cid = mcu_cmd; + uni_txd->seq = seq; + + return; + } + + mcu_txd = (struct mt7615_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, q_idx)); + mcu_txd->s2d_index = MCU_S2D_H2N; mcu_txd->pkt_type = MCU_PKT_ID; mcu_txd->seq = seq; @@ -97,10 +114,6 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb, mcu_txd->ext_cid = cmd; mcu_txd->ext_cid_ack = 1; } - mcu_txd->s2d_index = MCU_S2D_H2N; - - if (wait_seq) - *wait_seq = seq; } static int __mt7615_mcu_msg_send(struct mt7615_dev *dev, struct sk_buff *skb, diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h index 8ae08a2bf10d..3aad460e0809 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h @@ -23,6 +23,57 @@ struct mt7615_mcu_txd { u32 reserved[5]; } __packed __aligned(4); +/** + * struct mt7615_uni_txd - mcu command descriptor for firmware v3 + * @txd: hardware descriptor + * @len: total length not including txd + * @cid: command identifier + * @pkt_type: must be 0xa0 (cmd packet by long format) + * @frag_n: fragment number + * @seq: sequence number + * @checksum: 0 mean there is no checksum + * @s2d_index: index for command source and destination + * Definition | value | note + * CMD_S2D_IDX_H2N | 0x00 | command from HOST to WM + * CMD_S2D_IDX_C2N | 0x01 | command from WA to WM + * CMD_S2D_IDX_H2C | 0x02 | command from HOST to WA + * CMD_S2D_IDX_H2N_AND_H2C | 0x03 | command from HOST to WA and WM + * + * @option: command option + * BIT[0]: UNI_CMD_OPT_BIT_ACK + * set to 1 to request a fw reply + * if UNI_CMD_OPT_BIT_0_ACK is set and UNI_CMD_OPT_BIT_2_SET_QUERY + * is set, mcu firmware will send response event EID = 0x01 + * (UNI_EVENT_ID_CMD_RESULT) to the host. + * BIT[1]: UNI_CMD_OPT_BIT_UNI_CMD + * 0: original command + * 1: unified command + * BIT[2]: UNI_CMD_OPT_BIT_SET_QUERY + * 0: QUERY command + * 1: SET command + */ +struct mt7615_uni_txd { + __le32 txd[8]; + + /* DW1 */ + __le16 len; + __le16 cid; + + /* DW2 */ + u8 reserved; + u8 pkt_type; + u8 frag_n; + u8 seq; + + /* DW3 */ + __le16 checksum; + u8 s2d_index; + u8 option; + + /* DW4 */ + u8 reserved2[4]; +} __packed __aligned(4); + /* event table */ enum { MCU_EVENT_TARGET_ADDRESS_LEN = 0x01, @@ -180,7 +231,8 @@ enum { }; #define MCU_FW_PREFIX BIT(31) -#define MCU_CMD_MASK ~MCU_FW_PREFIX +#define MCU_UNI_PREFIX BIT(30) +#define MCU_CMD_MASK ~(MCU_FW_PREFIX | MCU_UNI_PREFIX) enum { MCU_CMD_TARGET_ADDRESS_LEN_REQ = MCU_FW_PREFIX | 0x01, @@ -217,6 +269,12 @@ enum { MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d, }; +#define MCU_CMD_ACK BIT(0) +#define MCU_CMD_UNI BIT(1) +#define MCU_CMD_QUERY BIT(2) + +#define MCU_CMD_UNI_EXT_ACK (MCU_CMD_ACK | MCU_CMD_UNI | MCU_CMD_QUERY) + enum { PATCH_SEM_RELEASE = 0x0, PATCH_SEM_GET = 0x1 -- 2.25.1