[][MAC80211][mt76][update mt76 patches]

[Description]
Add and sync mt76 patches for bug fixes and new features.

[Release-log]
N/A

Change-Id: I200bb0ca0b6aacff3b4517fbb62d835237e0359a
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/7218108
diff --git a/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
new file mode 100644
index 0000000..3de5b90
--- /dev/null
+++ b/autobuild_mac80211_release/mt7988_mt7996_mac80211/package/kernel/mt76/patches/0011-wifi-mt76-mt7996-add-thermal-sensor-device-support.patch
@@ -0,0 +1,184 @@
+From afdb511f0febad0e0cc5572461ab04794cf86852 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Thu, 2 Feb 2023 20:53:42 +0800
+Subject: [PATCH 11/19] wifi: mt76: mt7996: add thermal sensor device support
+
+---
+ mt7996/init.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ mt7996/mcu.c  | 41 ++++++++++++++++++++++++
+ 2 files changed, 128 insertions(+)
+
+diff --git a/mt7996/init.c b/mt7996/init.c
+index 5a22cd81..631ada15 100644
+--- a/mt7996/init.c
++++ b/mt7996/init.c
+@@ -4,6 +4,8 @@
+  */
+ 
+ #include <linux/etherdevice.h>
++#include <linux/hwmon.h>
++#include <linux/hwmon-sysfs.h>
+ #include <linux/thermal.h>
+ #include "mt7996.h"
+ #include "mac.h"
+@@ -41,6 +43,81 @@ static const struct ieee80211_iface_combination if_comb[] = {
+ 	}
+ };
+ 
++static ssize_t mt7996_thermal_temp_show(struct device *dev,
++					struct device_attribute *attr,
++					char *buf)
++{
++	struct mt7996_phy *phy = dev_get_drvdata(dev);
++	int i = to_sensor_dev_attr(attr)->index;
++	int temperature;
++
++	switch (i) {
++	case 0:
++		temperature = mt7996_mcu_get_temperature(phy);
++		if (temperature < 0)
++			return temperature;
++		/* display in millidegree celcius */
++		return sprintf(buf, "%u\n", temperature * 1000);
++	case 1:
++	case 2:
++		return sprintf(buf, "%u\n",
++			       phy->throttle_temp[i - 1] * 1000);
++	case 3:
++		return sprintf(buf, "%hhu\n", phy->throttle_state);
++	default:
++		return -EINVAL;
++	}
++}
++
++static ssize_t mt7996_thermal_temp_store(struct device *dev,
++					 struct device_attribute *attr,
++					 const char *buf, size_t count)
++{
++	struct mt7996_phy *phy = dev_get_drvdata(dev);
++	int ret, i = to_sensor_dev_attr(attr)->index;
++	long val;
++
++	ret = kstrtol(buf, 10, &val);
++	if (ret < 0)
++		return ret;
++
++	mutex_lock(&phy->dev->mt76.mutex);
++	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 40, 130);
++
++	if ((i - 1 == MT7996_CRIT_TEMP_IDX &&
++	     val > phy->throttle_temp[MT7996_MAX_TEMP_IDX]) ||
++	    (i - 1 == MT7996_MAX_TEMP_IDX &&
++	     val < phy->throttle_temp[MT7996_CRIT_TEMP_IDX])) {
++		dev_err(phy->dev->mt76.dev,
++			"temp1_max shall be greater than temp1_crit.");
++		mutex_unlock(&phy->dev->mt76.mutex);
++		return -EINVAL;
++	}
++
++	phy->throttle_temp[i - 1] = val;
++	mutex_unlock(&phy->dev->mt76.mutex);
++
++	ret = mt7996_mcu_set_thermal_protect(phy);
++	if (ret)
++		return ret;
++
++	return count;
++}
++
++static SENSOR_DEVICE_ATTR_RO(temp1_input, mt7996_thermal_temp, 0);
++static SENSOR_DEVICE_ATTR_RW(temp1_crit, mt7996_thermal_temp, 1);
++static SENSOR_DEVICE_ATTR_RW(temp1_max, mt7996_thermal_temp, 2);
++static SENSOR_DEVICE_ATTR_RO(throttle1, mt7996_thermal_temp, 3);
++
++static struct attribute *mt7996_hwmon_attrs[] = {
++	&sensor_dev_attr_temp1_input.dev_attr.attr,
++	&sensor_dev_attr_temp1_crit.dev_attr.attr,
++	&sensor_dev_attr_temp1_max.dev_attr.attr,
++	&sensor_dev_attr_throttle1.dev_attr.attr,
++	NULL,
++};
++ATTRIBUTE_GROUPS(mt7996_hwmon);
++
+ static int
+ mt7996_thermal_get_max_throttle_state(struct thermal_cooling_device *cdev,
+ 				      unsigned long *state)
+@@ -112,6 +189,7 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
+ {
+ 	struct wiphy *wiphy = phy->mt76->hw->wiphy;
+ 	struct thermal_cooling_device *cdev;
++	struct device *hwmon;
+ 	const char *name;
+ 
+ 	name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7996_%s",
+@@ -130,6 +208,15 @@ static int mt7996_thermal_init(struct mt7996_phy *phy)
+ 	phy->throttle_temp[MT7996_CRIT_TEMP_IDX] = MT7996_CRIT_TEMP;
+ 	phy->throttle_temp[MT7996_MAX_TEMP_IDX] = MT7996_MAX_TEMP;
+ 
++	if (!IS_REACHABLE(CONFIG_HWMON))
++		return 0;
++
++	hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy,
++						       mt7996_hwmon_groups);
++
++	if (IS_ERR(hwmon))
++		return PTR_ERR(hwmon);
++
+ 	return 0;
+ }
+ 
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index 3820a63e..b3326586 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -3308,6 +3308,47 @@ out:
+ 	return 0;
+ }
+ 
++int mt7996_mcu_get_temperature(struct mt7996_phy *phy)
++{
++#define TEMPERATURE_QUERY 0
++#define GET_TEMPERATURE 0
++	struct {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		u8 rsv1;
++		u8 action;
++		u8 band_idx;
++		u8 rsv2;
++	} req = {
++		.tag = cpu_to_le16(TEMPERATURE_QUERY),
++		.len = cpu_to_le16(sizeof(req) - 4),
++		.action = GET_TEMPERATURE,
++		.band_idx = phy->mt76->band_idx,
++	};
++	struct mt7996_mcu_thermal {
++		u8 _rsv[4];
++
++		__le16 tag;
++		__le16 len;
++
++		__le32 rsv;
++		__le32 temperature;
++	} __packed *res;
++	struct sk_buff *skb;
++	int ret;
++
++	ret = mt76_mcu_send_and_get_msg(&phy->dev->mt76, MCU_WM_UNI_CMD(THERMAL),
++					&req, sizeof(req), true, &skb);
++	if (ret)
++		return ret;
++
++	res = (void *)skb->data;
++
++	return le32_to_cpu(res->temperature);
++}
+ 
+ int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state)
+ {
+-- 
+2.39.2
+