mt76: mt7615: add support for accessing RF registers via MCU
authorFelix Fietkau <nbd@nbd.name>
Thu, 18 Jun 2020 18:33:32 +0000 (20:33 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 21 Jul 2020 17:01:15 +0000 (19:01 +0200)
Includes debugfs files for testing it.
Will be used for testmode support.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h

index d06afcf46d67ccde47bd0466b053891c3b6f7731..8bb7c64db73818fd5e23d96d76011786e1ecbf98 100644 (file)
@@ -285,6 +285,29 @@ mt7615_queues_read(struct seq_file *s, void *data)
        return 0;
 }
 
+static int
+mt7615_rf_reg_set(void *data, u64 val)
+{
+       struct mt7615_dev *dev = data;
+
+       mt7615_rf_wr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg, val);
+
+       return 0;
+}
+
+static int
+mt7615_rf_reg_get(void *data, u64 *val)
+{
+       struct mt7615_dev *dev = data;
+
+       *val = mt7615_rf_rr(dev, dev->debugfs_rf_wf, dev->debugfs_rf_reg);
+
+       return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_reg, mt7615_rf_reg_get, mt7615_rf_reg_set,
+                        "0x%08llx\n");
+
 int mt7615_init_debugfs(struct mt7615_dev *dev)
 {
        struct dentry *dir;
@@ -324,6 +347,11 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
        debugfs_create_devm_seqfile(dev->mt76.dev, "temperature", dir,
                                    mt7615_read_temperature);
 
+       debugfs_create_u32("rf_wfidx", 0600, dir, &dev->debugfs_rf_wf);
+       debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
+       debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
+                                  &fops_rf_reg);
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(mt7615_init_debugfs);
index d3a8ada3b779c4c3f87b4630341b595b8a3c005f..b4440f131925e5e638250f00918df58b5eb366b0 100644 (file)
@@ -151,8 +151,11 @@ void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
                break;
        default:
                mcu_txd->cid = MCU_CMD_EXT_CID;
-               mcu_txd->set_query = MCU_Q_SET;
-               mcu_txd->ext_cid = cmd;
+               if (cmd & MCU_QUERY_PREFIX)
+                       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;
        }
@@ -192,6 +195,10 @@ mt7615_mcu_parse_response(struct mt7615_dev *dev, int cmd,
                skb_pull(skb, sizeof(*rxd));
                ret = le32_to_cpu(*(__le32 *)skb->data);
                break;
+       case MCU_EXT_CMD_RF_REG_ACCESS | MCU_QUERY_PREFIX:
+               skb_pull(skb, sizeof(*rxd));
+               ret = le32_to_cpu(*(__le32 *)&skb->data[8]);
+               break;
        case MCU_UNI_CMD_DEV_INFO_UPDATE:
        case MCU_UNI_CMD_BSS_INFO_UPDATE:
        case MCU_UNI_CMD_STA_REC_UPDATE:
@@ -271,6 +278,38 @@ int mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
 }
 EXPORT_SYMBOL_GPL(mt7615_mcu_msg_send);
 
+u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg)
+{
+       struct {
+               __le32 wifi_stream;
+               __le32 address;
+               __le32 data;
+       } req = {
+               .wifi_stream = cpu_to_le32(wf),
+               .address = cpu_to_le32(reg),
+       };
+
+       return __mt76_mcu_send_msg(&dev->mt76,
+                                  MCU_EXT_CMD_RF_REG_ACCESS | MCU_QUERY_PREFIX,
+                                  &req, sizeof(req), true);
+}
+
+int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val)
+{
+       struct {
+               __le32 wifi_stream;
+               __le32 address;
+               __le32 data;
+       } req = {
+               .wifi_stream = cpu_to_le32(wf),
+               .address = cpu_to_le32(reg),
+               .data = cpu_to_le32(val),
+       };
+
+       return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RF_REG_ACCESS, &req,
+                                  sizeof(req), false);
+}
+
 static void
 mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
 {
index 4f70c4de69a43a47eea466fb81d0531f4d8a8c5f..8e2be150a5563f80ad9a42557773df8556565dbe 100644 (file)
@@ -238,8 +238,9 @@ enum {
 #define MCU_FW_PREFIX          BIT(31)
 #define MCU_UNI_PREFIX         BIT(30)
 #define MCU_CE_PREFIX          BIT(29)
+#define MCU_QUERY_PREFIX       BIT(28)
 #define MCU_CMD_MASK           ~(MCU_FW_PREFIX | MCU_UNI_PREFIX |      \
-                                 MCU_CE_PREFIX)
+                                 MCU_CE_PREFIX | MCU_QUERY_PREFIX)
 
 enum {
        MCU_CMD_TARGET_ADDRESS_LEN_REQ = MCU_FW_PREFIX | 0x01,
@@ -254,6 +255,7 @@ enum {
 };
 
 enum {
+       MCU_EXT_CMD_RF_REG_ACCESS = 0x02,
        MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
        MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
        MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11,
index 78cc2a2c31f71118fb30bcf1d1f9094af3ee51bb..6e423f45b63f12fdd277897a462278a270b36b67 100644 (file)
@@ -281,6 +281,9 @@ struct mt7615_dev {
 
        struct work_struct wtbl_work;
        struct list_head wd_head;
+
+       u32 debugfs_rf_wf;
+       u32 debugfs_rf_reg;
 };
 
 enum tx_pkt_queue_idx {
@@ -522,6 +525,8 @@ u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid);
 int mt7615_mcu_wait_response(struct mt7615_dev *dev, int cmd, int seq);
 int mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
                        int len, bool wait_resp);
+u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg);
+int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val);
 int mt7615_mcu_set_dbdc(struct mt7615_dev *dev);
 int mt7615_mcu_set_eeprom(struct mt7615_dev *dev);
 int mt7615_mcu_set_mac_enable(struct mt7615_dev *dev, int band, bool enable);