wil6210: add sysfs for thermal throttling configuration

New sysfs entry "thermal_throttling" can be used to configure
boundaries of each thermal zone.
There are two sets of configurations, one for baseband and one for rf.
Each config contains 3 thermal zones: high, max, critical.
Each zone has high and low temperature set points (in Celsius).
The format for writing is a series of 12 unsigned bytes:
<bb_zone1_high> <bb_zone1_low> <bb_zone2_high> <bb_zone2_low> \
<bb_zone3_high> <bb_zone3_low> <rf_zone1_high> <rf_zone1_low> \
<rf_zone2_high> <rf_zone2_low> <rf_zone3_high> <rf_zone3_low>
To disable thermal throttling for baseband or for rf, use 0 for all
its six set points.

Change-Id: I6990cc0e8375905e4d95e2533d2188be785d9f4a
Signed-off-by: Dedy Lansky <dlansky@codeaurora.org>
[ailizaro@codeaurora.org: trivial conflict fixes]
Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
[liord@codeaurora.org: fix merge conflicts]
Signed-off-by: Lior David <liord@codeaurora.org>
This commit is contained in:
Dedy Lansky 2017-11-13 09:52:41 +02:00 • committed by Alexei Avshalom Lazar
commit c635afc0fb
4 changed files with 183 additions and 0 deletions

View file

@ -1767,6 +1767,9 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
return rc;
}
if (wil->tt_data_set)
wmi_set_tt_cfg(wil, &wil->tt_data);
wil_collect_fw_info(wil);
if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT)

View file

@ -81,8 +81,119 @@ ftm_txrx_offset_store(struct device *dev,
static DEVICE_ATTR_RW(ftm_txrx_offset);
static ssize_t
thermal_throttling_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct wil6210_priv *wil = dev_get_drvdata(dev);
ssize_t len;
struct wmi_tt_data tt_data;
int i, rc;
rc = wmi_get_tt_cfg(wil, &tt_data);
if (rc)
return rc;
len = snprintf(buf, PAGE_SIZE, " high max critical\n");
len += snprintf(buf + len, PAGE_SIZE - len, "bb: ");
if (tt_data.bb_enabled)
for (i = 0; i < WMI_NUM_OF_TT_ZONES; ++i)
len += snprintf(buf + len, PAGE_SIZE - len,
"%03d-%03d ",
tt_data.bb_zones[i].temperature_high,
tt_data.bb_zones[i].temperature_low);
else
len += snprintf(buf + len, PAGE_SIZE - len, "* disabled *");
len += snprintf(buf + len, PAGE_SIZE - len, "\nrf: ");
if (tt_data.rf_enabled)
for (i = 0; i < WMI_NUM_OF_TT_ZONES; ++i)
len += snprintf(buf + len, PAGE_SIZE - len,
"%03d-%03d ",
tt_data.rf_zones[i].temperature_high,
tt_data.rf_zones[i].temperature_low);
else
len += snprintf(buf + len, PAGE_SIZE - len, "* disabled *");
len += snprintf(buf + len, PAGE_SIZE - len, "\n");
return len;
}
static ssize_t
thermal_throttling_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct wil6210_priv *wil = dev_get_drvdata(dev);
int i, rc = -EINVAL;
char *token, *dupbuf, *tmp;
struct wmi_tt_data tt_data = {
.bb_enabled = 0,
.rf_enabled = 0,
};
tmp = kmemdup(buf, count + 1, GFP_KERNEL);
if (!tmp)
return -ENOMEM;
tmp[count] = '\0';
dupbuf = tmp;
/* Format for writing is 12 unsigned bytes separated by spaces:
* <bb_z1_h> <bb_z1_l> <bb_z2_h> <bb_z2_l> <bb_z3_h> <bb_z3_l> \
* <rf_z1_h> <rf_z1_l> <rf_z2_h> <rf_z2_l> <rf_z3_h> <rf_z3_l>
* To disable thermal throttling for bb or for rf, use 0 for all
* its six set points.
*/
/* bb */
for (i = 0; i < WMI_NUM_OF_TT_ZONES; ++i) {
token = strsep(&dupbuf, " ");
if (!token)
goto out;
if (kstrtou8(token, 0, &tt_data.bb_zones[i].temperature_high))
goto out;
token = strsep(&dupbuf, " ");
if (!token)
goto out;
if (kstrtou8(token, 0, &tt_data.bb_zones[i].temperature_low))
goto out;
if (tt_data.bb_zones[i].temperature_high > 0 ||
tt_data.bb_zones[i].temperature_low > 0)
tt_data.bb_enabled = 1;
}
/* rf */
for (i = 0; i < WMI_NUM_OF_TT_ZONES; ++i) {
token = strsep(&dupbuf, " ");
if (!token)
goto out;
if (kstrtou8(token, 0, &tt_data.rf_zones[i].temperature_high))
goto out;
token = strsep(&dupbuf, " ");
if (!token)
goto out;
if (kstrtou8(token, 0, &tt_data.rf_zones[i].temperature_low))
goto out;
if (tt_data.rf_zones[i].temperature_high > 0 ||
tt_data.rf_zones[i].temperature_low > 0)
tt_data.rf_enabled = 1;
}
rc = wmi_set_tt_cfg(wil, &tt_data);
if (rc)
goto out;
rc = count;
out:
kfree(tmp);
return rc;
}
static DEVICE_ATTR_RW(thermal_throttling);
static struct attribute *wil6210_sysfs_entries[] = {
&dev_attr_ftm_txrx_offset.attr,
&dev_attr_thermal_throttling.attr,
NULL
};

View file

@ -1036,6 +1036,8 @@ struct wil6210_priv {
enum wmi_ps_profile_type ps_profile;
int fw_calib_result;
u8 tt_data_set;
struct wmi_tt_data tt_data;
struct notifier_block pm_notify;
@ -1276,6 +1278,8 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid);
int wmi_set_tt_cfg(struct wil6210_priv *wil, struct wmi_tt_data *tt_data);
int wmi_get_tt_cfg(struct wil6210_priv *wil, struct wmi_tt_data *tt_data);
int wmi_port_allocate(struct wil6210_priv *wil, u8 mid,
const u8 *mac, enum nl80211_iftype iftype);
int wmi_port_delete(struct wil6210_priv *wil, u8 mid);

View file

@ -3067,6 +3067,71 @@ int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid)
return rc;
}
int wmi_set_tt_cfg(struct wil6210_priv *wil, struct wmi_tt_data *tt_data)
{
struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
int rc;
struct wmi_set_thermal_throttling_cfg_cmd cmd = {
.tt_data = *tt_data,
};
struct {
struct wmi_cmd_hdr wmi;
struct wmi_set_thermal_throttling_cfg_event evt;
} __packed reply;
if (!test_bit(WMI_FW_CAPABILITY_THERMAL_THROTTLING,
wil->fw_capabilities))
return -EOPNOTSUPP;
memset(&reply, 0, sizeof(reply));
rc = wmi_call(wil, WMI_SET_THERMAL_THROTTLING_CFG_CMDID, vif->mid,
&cmd, sizeof(cmd),
WMI_SET_THERMAL_THROTTLING_CFG_EVENTID,
&reply, sizeof(reply), 100);
if (rc) {
wil_err(wil, "failed to set thermal throttling\n");
return rc;
}
if (reply.evt.status) {
wil_err(wil, "set thermal throttling failed, error %d\n",
reply.evt.status);
return -EIO;
}
wil->tt_data = *tt_data;
wil->tt_data_set = true;
return 0;
}
int wmi_get_tt_cfg(struct wil6210_priv *wil, struct wmi_tt_data *tt_data)
{
struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
int rc;
struct {
struct wmi_cmd_hdr wmi;
struct wmi_get_thermal_throttling_cfg_event evt;
} __packed reply;
if (!test_bit(WMI_FW_CAPABILITY_THERMAL_THROTTLING,
wil->fw_capabilities))
return -EOPNOTSUPP;
rc = wmi_call(wil, WMI_GET_THERMAL_THROTTLING_CFG_CMDID, vif->mid,
NULL, 0, WMI_GET_THERMAL_THROTTLING_CFG_EVENTID, &reply,
sizeof(reply), 100);
if (rc) {
wil_err(wil, "failed to get thermal throttling\n");
return rc;
}
if (tt_data)
*tt_data = reply.evt.tt_data;
return 0;
}
void wmi_event_flush(struct wil6210_priv *wil)
{
ulong flags;