bnxt_en: Expose threshold temperatures through hwmon
authorKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Wed, 27 Sep 2023 03:57:30 +0000 (20:57 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 4 Oct 2023 10:23:01 +0000 (11:23 +0100)
HWRM_TEMP_MONITOR_QUERY response now indicates various
threshold temperatures. Expose these threshold temperatures
through the hwmon sysfs using this mapping:

hwmon_temp_max : bp->warn_thresh_temp
hwmon_temp_crit : bp->crit_thresh_temp
hwmon_temp_emergency : bp->fatal_thresh_temp

hwmon_temp_max_alarm : temp >= bp->warn_thresh_temp
hwmon_temp_crit_alarm : temp >= bp->crit_thresh_temp
hwmon_temp_emergency_alarm : temp >= bp->fatal_thresh_temp

Link: https://lore.kernel.org/netdev/20230815045658.80494-12-michael.chan@broadcom.com/
Cc: Jean Delvare <jdelvare@suse.com>
Cc: Guenter Roeck <linux@roeck-us.net>
Cc: linux-hwmon@vger.kernel.org
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_hwmon.c

index 84cbcfa61bc12f78b2ac59b2527e7cc07c529a2a..43a07d84f815873bb1428ae3d041e89b7de37814 100644 (file)
@@ -2013,6 +2013,7 @@ struct bnxt {
        #define BNXT_FW_CAP_RING_MONITOR                BIT_ULL(30)
        #define BNXT_FW_CAP_DBG_QCAPS                   BIT_ULL(31)
        #define BNXT_FW_CAP_PTP                         BIT_ULL(32)
+       #define BNXT_FW_CAP_THRESHOLD_TEMP_SUPPORTED    BIT_ULL(33)
 
        u32                     fw_dbg_cap;
 
@@ -2185,7 +2186,13 @@ struct bnxt {
        struct bnxt_tc_info     *tc_info;
        struct list_head        tc_indr_block_list;
        struct dentry           *debugfs_pdev;
+#ifdef CONFIG_BNXT_HWMON
        struct device           *hwmon_dev;
+       u8                      warn_thresh_temp;
+       u8                      crit_thresh_temp;
+       u8                      fatal_thresh_temp;
+       u8                      shutdown_thresh_temp;
+#endif
        enum board_idx          board_idx;
 };
 
index 05e3d75f3c43de6f11f1f51d75e3a1421f3bf99d..6a2cad5cc159470c970c7fdd143124cad9210b06 100644 (file)
@@ -32,8 +32,16 @@ static int bnxt_hwrm_temp_query(struct bnxt *bp, u8 *temp)
        if (rc)
                goto drop_req;
 
-       *temp = resp->temp;
-
+       if (temp) {
+               *temp = resp->temp;
+       } else if (resp->flags &
+                  TEMP_MONITOR_QUERY_RESP_FLAGS_THRESHOLD_VALUES_AVAILABLE) {
+               bp->fw_cap |= BNXT_FW_CAP_THRESHOLD_TEMP_SUPPORTED;
+               bp->warn_thresh_temp = resp->warn_threshold;
+               bp->crit_thresh_temp = resp->critical_threshold;
+               bp->fatal_thresh_temp = resp->fatal_threshold;
+               bp->shutdown_thresh_temp = resp->shutdown_threshold;
+       }
 drop_req:
        hwrm_req_drop(bp, req);
        return rc;
@@ -42,12 +50,23 @@ drop_req:
 static umode_t bnxt_hwmon_is_visible(const void *_data, enum hwmon_sensor_types type,
                                     u32 attr, int channel)
 {
+       const struct bnxt *bp = _data;
+
        if (type != hwmon_temp)
                return 0;
 
        switch (attr) {
        case hwmon_temp_input:
                return 0444;
+       case hwmon_temp_max:
+       case hwmon_temp_crit:
+       case hwmon_temp_emergency:
+       case hwmon_temp_max_alarm:
+       case hwmon_temp_crit_alarm:
+       case hwmon_temp_emergency_alarm:
+               if (!(bp->fw_cap & BNXT_FW_CAP_THRESHOLD_TEMP_SUPPORTED))
+                       return 0;
+               return 0444;
        default:
                return 0;
        }
@@ -66,13 +85,39 @@ static int bnxt_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32
                if (!rc)
                        *val = temp * 1000;
                return rc;
+       case hwmon_temp_max:
+               *val = bp->warn_thresh_temp * 1000;
+               return 0;
+       case hwmon_temp_crit:
+               *val = bp->crit_thresh_temp * 1000;
+               return 0;
+       case hwmon_temp_emergency:
+               *val = bp->fatal_thresh_temp * 1000;
+               return 0;
+       case hwmon_temp_max_alarm:
+               rc = bnxt_hwrm_temp_query(bp, &temp);
+               if (!rc)
+                       *val = temp >= bp->warn_thresh_temp;
+               return rc;
+       case hwmon_temp_crit_alarm:
+               rc = bnxt_hwrm_temp_query(bp, &temp);
+               if (!rc)
+                       *val = temp >= bp->crit_thresh_temp;
+               return rc;
+       case hwmon_temp_emergency_alarm:
+               rc = bnxt_hwrm_temp_query(bp, &temp);
+               if (!rc)
+                       *val = temp >= bp->fatal_thresh_temp;
+               return rc;
        default:
                return -EOPNOTSUPP;
        }
 }
 
 static const struct hwmon_channel_info *bnxt_hwmon_info[] = {
-       HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+       HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
+                          HWMON_T_EMERGENCY | HWMON_T_MAX_ALARM |
+                          HWMON_T_CRIT_ALARM | HWMON_T_EMERGENCY_ALARM),
        NULL
 };
 
@@ -96,13 +141,11 @@ void bnxt_hwmon_uninit(struct bnxt *bp)
 
 void bnxt_hwmon_init(struct bnxt *bp)
 {
-       struct hwrm_temp_monitor_query_input *req;
        struct pci_dev *pdev = bp->pdev;
        int rc;
 
-       rc = hwrm_req_init(bp, req, HWRM_TEMP_MONITOR_QUERY);
-       if (!rc)
-               rc = hwrm_req_send_silent(bp, req);
+       /* temp1_xxx is only sensor, ensure not registered if it will fail */
+       rc = bnxt_hwrm_temp_query(bp, NULL);
        if (rc == -EACCES || rc == -EOPNOTSUPP) {
                bnxt_hwmon_uninit(bp);
                return;