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