Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8142d11 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "wil6210: send uevent when creating sysfs files"

parents 00a0a504 cf3b97fa
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -41,6 +41,10 @@ static struct wiphy_wowlan_support wil_wowlan_support = {
};
#endif

static bool ignore_reg_hints = true;
module_param(ignore_reg_hints, bool, 0444);
MODULE_PARM_DESC(ignore_reg_hints, " Ignore OTA regulatory hints (Default: true)");

#define CHAN60G(_channel, _flags) {				\
	.band			= NL80211_BAND_60GHZ,		\
	.center_freq		= 56160 + (2160 * (_channel)),	\
@@ -2725,6 +2729,11 @@ static void wil_wiphy_init(struct wiphy *wiphy)
	wiphy->vendor_events = wil_nl80211_vendor_events;
	wiphy->n_vendor_events = ARRAY_SIZE(wil_nl80211_vendor_events);

	if (ignore_reg_hints) {
		wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
		wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
	}

#ifdef CONFIG_PM
	wiphy->wowlan = &wil_wowlan_support;
#endif
+4 −0
Original line number Diff line number Diff line
@@ -271,6 +271,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
			break;
		}
		sta->status = wil_sta_unused;
		sta->fst_link_loss = false;
		sta->mid = U8_MAX;
	}
	/* reorder buffers */
@@ -1767,6 +1768,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)
+177 −0
Original line number Diff line number Diff line
@@ -81,8 +81,182 @@ 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 ssize_t
fst_link_loss_show(struct device *dev, struct device_attribute *attr,
		   char *buf)
{
	struct wil6210_priv *wil = dev_get_drvdata(dev);
	ssize_t len = 0;
	int i;

	for (i = 0; i < ARRAY_SIZE(wil->sta); i++)
		if (wil->sta[i].status == wil_sta_connected)
			len += snprintf(buf + len, PAGE_SIZE - len,
					"[%d] %pM %s\n", i, wil->sta[i].addr,
					wil->sta[i].fst_link_loss ?
					"On" : "Off");

	return len;
}

static ssize_t
fst_link_loss_store(struct device *dev, struct device_attribute *attr,
		    const char *buf, size_t count)
{
	struct wil6210_priv *wil = dev_get_drvdata(dev);
	u8 addr[ETH_ALEN];
	char *token, *dupbuf, *tmp;
	int rc = -EINVAL;
	bool fst_link_loss;

	tmp = kmemdup(buf, count + 1, GFP_KERNEL);
	if (!tmp)
		return -ENOMEM;

	tmp[count] = '\0';
	dupbuf = tmp;

	token = strsep(&dupbuf, " ");
	if (!token)
		goto out;

	/* mac address */
	if (sscanf(token, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
		   &addr[0], &addr[1], &addr[2],
		   &addr[3], &addr[4], &addr[5]) != 6)
		goto out;

	/* On/Off */
	if (strtobool(dupbuf, &fst_link_loss))
		goto out;

	wil_dbg_misc(wil, "set [%pM] with %d\n", addr, fst_link_loss);

	rc = wmi_link_maintain_cfg_write(wil, addr, fst_link_loss);
	if (!rc)
		rc = count;

out:
	kfree(tmp);
	return rc;
}

static DEVICE_ATTR_RW(fst_link_loss);

static struct attribute *wil6210_sysfs_entries[] = {
	&dev_attr_ftm_txrx_offset.attr,
	&dev_attr_thermal_throttling.attr,
	&dev_attr_fst_link_loss.attr,
	NULL
};

@@ -102,6 +276,8 @@ int wil6210_sysfs_init(struct wil6210_priv *wil)
		return err;
	}

	kobject_uevent(&dev->kobj, KOBJ_CHANGE);

	return 0;
}

@@ -110,4 +286,5 @@ void wil6210_sysfs_remove(struct wil6210_priv *wil)
	struct device *dev = wil_to_dev(wil);

	sysfs_remove_group(&dev->kobj, &wil6210_attribute_group);
	kobject_uevent(&dev->kobj, KOBJ_CHANGE);
}
+9 −0
Original line number Diff line number Diff line
@@ -756,6 +756,7 @@ struct wil_sta_info {
	struct wil_tid_crypto_rx tid_crypto_rx[WIL_STA_TID_NUM];
	struct wil_tid_crypto_rx group_crypto_rx;
	u8 aid; /* 1-254; 0 if unknown/not reported */
	u8 fst_link_loss;
};

enum {
@@ -1036,6 +1037,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 +1279,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);
@@ -1430,6 +1435,10 @@ void wil_ftm_evt_per_dest_res(struct wil6210_vif *vif,
void wil_aoa_evt_meas(struct wil6210_vif *vif,
		      struct wmi_aoa_meas_event *evt,
		      int len);
/* link loss */
int wmi_link_maintain_cfg_write(struct wil6210_priv *wil,
				const u8 *addr,
				bool fst_link_loss);

int wmi_start_sched_scan(struct wil6210_priv *wil,
			 struct cfg80211_sched_scan_request *request);
+124 −0
Original line number Diff line number Diff line
@@ -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;
@@ -3215,6 +3280,65 @@ int wmi_resume(struct wil6210_priv *wil)
	return reply.evt.status;
}

int wmi_link_maintain_cfg_write(struct wil6210_priv *wil,
				const u8 *addr,
				bool fst_link_loss)
{
	struct net_device *ndev = wil->main_ndev;
	struct wireless_dev *wdev = ndev->ieee80211_ptr;
	struct wil6210_vif *vif = ndev_to_vif(ndev);
	int rc;
	int cid = wil_find_cid(wil, vif->mid, addr);
	u32 cfg_type;
	struct wmi_link_maintain_cfg_write_cmd cmd;
	struct {
		struct wmi_cmd_hdr wmi;
		struct wmi_link_maintain_cfg_write_done_event evt;
	} __packed reply;

	if (cid < 0)
		return cid;

	switch (wdev->iftype) {
	case NL80211_IFTYPE_STATION:
		cfg_type = fst_link_loss ?
			   WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_STA :
			   WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_STA;
		break;
	case NL80211_IFTYPE_AP:
		cfg_type = fst_link_loss ?
			   WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_FST_AP :
			   WMI_LINK_MAINTAIN_CFG_TYPE_DEFAULT_NORMAL_AP;
		break;
	default:
		wil_err(wil, "Unsupported for iftype %d", wdev->iftype);
		return -EINVAL;
	}

	wil_dbg_misc(wil, "Setting cid:%d with cfg_type:%d\n", cid, cfg_type);

	cmd.cfg_type = cpu_to_le32(cfg_type);
	cmd.cid = cpu_to_le32(cid);

	reply.evt.status = cpu_to_le32(WMI_FW_STATUS_FAILURE);

	rc = wmi_call(wil, WMI_LINK_MAINTAIN_CFG_WRITE_CMDID, vif->mid,
		      &cmd, sizeof(cmd),
		      WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID, &reply,
		      sizeof(reply), 250);
	if (rc) {
		wil_err(wil, "Failed to %s FST link loss",
			fst_link_loss ? "enable" : "disable");
	} else if (reply.evt.status == WMI_FW_STATUS_SUCCESS) {
		wil->sta[cid].fst_link_loss = fst_link_loss;
	} else {
		wil_err(wil, "WMI_LINK_MAINTAIN_CFG_WRITE_CMDID returned status %d",
			reply.evt.status);
		rc = -EINVAL;
	}
	return rc;
}

int wmi_port_allocate(struct wil6210_priv *wil, u8 mid,
		      const u8 *mac, enum nl80211_iftype iftype)
{