iwlwifi: pcie: identify the RF module
authorJohannes Berg <johannes.berg@intel.com>
Thu, 17 Jun 2021 07:08:41 +0000 (10:08 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 22 Jun 2021 12:11:26 +0000 (15:11 +0300)
Identify and print out the RF module to be able to identify
(from logs and through debugfs) which one (and version) is
present on the system.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210617100544.cd1ef97b2c04.Iad42a59902a87a50b45b9ce88705863686a83b54@changeid
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/iwl-prph.h
drivers/net/wireless/intel/iwlwifi/pcie/internal.h
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c

index 3ce77e4..9a9e714 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2005-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2021 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016 Intel Deutschland GmbH
  */
@@ -412,6 +412,8 @@ enum {
 #define UREG_DOORBELL_TO_ISR6_RESUME   BIT(19)
 #define UREG_DOORBELL_TO_ISR6_PNVM     BIT(20)
 
+#define CNVI_MBOX_C                    0xA3400C
+
 #define FSEQ_ERROR_CODE                        0xA340C8
 #define FSEQ_TOP_INIT_VERSION          0xA34038
 #define FSEQ_CNVIO_INIT_VERSION                0xA3403C
index 76a512c..9077817 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * Copyright (C) 2003-2015, 2018-2020 Intel Corporation
+ * Copyright (C) 2003-2015, 2018-2021 Intel Corporation
  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
  * Copyright (C) 2016-2017 Intel Deutschland GmbH
  */
@@ -317,6 +317,7 @@ struct cont_rec {
  * @alloc_page_lock: spinlock for the page allocator
  * @alloc_page: allocated page to still use parts of
  * @alloc_page_used: how much of the allocated page was already used (bytes)
+ * @rf_name: name/version of the CRF, if any
  */
 struct iwl_trans_pcie {
        struct iwl_rxq *rxq;
@@ -409,6 +410,8 @@ struct iwl_trans_pcie {
        bool fw_reset_handshake;
        bool fw_reset_done;
        wait_queue_head_t fw_reset_waitq;
+
+       char rf_name[32];
 };
 
 static inline struct iwl_trans_pcie *
index 1bcd36e..56162c4 100644 (file)
@@ -240,6 +240,75 @@ static int iwl_pcie_gen2_nic_init(struct iwl_trans *trans)
        return 0;
 }
 
+static void iwl_pcie_get_rf_name(struct iwl_trans *trans)
+{
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+       char *buf = trans_pcie->rf_name;
+       size_t buflen = sizeof(trans_pcie->rf_name);
+       size_t pos;
+       u32 version;
+
+       if (buf[0])
+               return;
+
+       switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) {
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_JF):
+               pos = scnprintf(buf, buflen, "JF");
+               break;
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF):
+               pos = scnprintf(buf, buflen, "GF");
+               break;
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_GF4):
+               pos = scnprintf(buf, buflen, "GF4");
+               break;
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR):
+               pos = scnprintf(buf, buflen, "HR");
+               break;
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR1):
+               pos = scnprintf(buf, buflen, "HR1");
+               break;
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HRCDB):
+               pos = scnprintf(buf, buflen, "HRCDB");
+               break;
+       default:
+               return;
+       }
+
+       switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) {
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR):
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HR1):
+       case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HRCDB):
+               version = iwl_read_prph(trans, CNVI_MBOX_C);
+               switch (version) {
+               case 0x20000:
+                       pos += scnprintf(buf + pos, buflen - pos, " B3");
+                       break;
+               case 0x120000:
+                       pos += scnprintf(buf + pos, buflen - pos, " B5");
+                       break;
+               default:
+                       pos += scnprintf(buf + pos, buflen - pos,
+                                        " (0x%x)", version);
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+
+       pos += scnprintf(buf + pos, buflen - pos, ", rfid=0x%x",
+                        trans->hw_rf_id);
+
+       IWL_INFO(trans, "Detected RF %s\n", buf);
+
+       /*
+        * also add a \n for debugfs - need to do it after printing
+        * since our IWL_INFO machinery wants to see a static \n at
+        * the end of the string
+        */
+       pos += scnprintf(buf + pos, buflen - pos, "\n");
+}
+
 void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
 {
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -263,6 +332,8 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
        iwl_enable_interrupts(trans);
        mutex_lock(&trans_pcie->mutex);
        iwl_pcie_check_hw_rf_kill(trans);
+
+       iwl_pcie_get_rf_name(trans);
        mutex_unlock(&trans_pcie->mutex);
 }
 
index 5b40833..1331a6b 100644 (file)
@@ -2848,11 +2848,28 @@ static ssize_t iwl_dbgfs_monitor_data_read(struct file *file,
        return bytes_copied;
 }
 
+static ssize_t iwl_dbgfs_rf_read(struct file *file,
+                                char __user *user_buf,
+                                size_t count, loff_t *ppos)
+{
+       struct iwl_trans *trans = file->private_data;
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+       if (!trans_pcie->rf_name[0])
+               return -ENODEV;
+
+       return simple_read_from_buffer(user_buf, count, ppos,
+                                      trans_pcie->rf_name,
+                                      strlen(trans_pcie->rf_name));
+}
+
 DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 DEBUGFS_READ_FILE_OPS(fh_reg);
 DEBUGFS_READ_FILE_OPS(rx_queue);
 DEBUGFS_WRITE_FILE_OPS(csr);
 DEBUGFS_READ_WRITE_FILE_OPS(rfkill);
+DEBUGFS_READ_FILE_OPS(rf);
+
 static const struct file_operations iwl_dbgfs_tx_queue_ops = {
        .owner = THIS_MODULE,
        .open = iwl_dbgfs_tx_queue_open,
@@ -2879,6 +2896,7 @@ void iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)
        DEBUGFS_ADD_FILE(fh_reg, dir, 0400);
        DEBUGFS_ADD_FILE(rfkill, dir, 0600);
        DEBUGFS_ADD_FILE(monitor_data, dir, 0400);
+       DEBUGFS_ADD_FILE(rf, dir, 0400);
 }
 
 static void iwl_trans_pcie_debugfs_cleanup(struct iwl_trans *trans)